Last active
May 16, 2026 15:41
-
-
Save felipealfonsog/60a139c1d0b65af5e5e6581fea345a15 to your computer and use it in GitHub Desktop.
Install OneDrive as a service
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| REAL_BIN="/usr/bin/onedrive" | |
| WRAPPER="$HOME/.local/bin/onedrive" | |
| CONFIG_DIR="$HOME/.config/onedrive" | |
| CONFIG_FILE="$CONFIG_DIR/config" | |
| SYNC_DIR="$HOME/OneDrive" | |
| SERVICE_DIR="$HOME/.config/systemd/user" | |
| SERVICE_FILE="$SERVICE_DIR/onedrive-safe.service" | |
| SERVICE_NAME="onedrive-safe.service" | |
| install_onedrive() { | |
| if [[ -x "$REAL_BIN" ]]; then | |
| echo "Using existing OneDrive client: $REAL_BIN" | |
| return 0 | |
| fi | |
| if command -v pacman >/dev/null 2>&1; then | |
| sudo pacman -S --needed git base-devel curl | |
| if command -v yay >/dev/null 2>&1; then | |
| yay -S --needed onedrive-abraunegg | |
| elif command -v paru >/dev/null 2>&1; then | |
| paru -S --needed onedrive-abraunegg | |
| else | |
| echo "Missing AUR helper: yay or paru." | |
| exit 1 | |
| fi | |
| elif command -v apt >/dev/null 2>&1; then | |
| sudo apt update | |
| sudo apt install -y onedrive | |
| elif command -v dnf >/dev/null 2>&1; then | |
| sudo dnf install -y onedrive | |
| else | |
| echo "Unsupported package manager." | |
| exit 1 | |
| fi | |
| if [[ ! -x "$REAL_BIN" ]]; then | |
| echo "OneDrive client was not installed correctly." | |
| exit 1 | |
| fi | |
| } | |
| write_safe_config() { | |
| mkdir -p "$CONFIG_DIR" | |
| mkdir -p "$SYNC_DIR" | |
| THREADS="$(nproc 2>/dev/null || echo 2)" | |
| cat > "$CONFIG_FILE" <<EOF | |
| sync_dir = "$SYNC_DIR" | |
| download_only = "true" | |
| upload_only = "false" | |
| remove_source_files = "false" | |
| skip_symlinks = "true" | |
| skip_file = "~*|.~*|*.tmp|*.swp|*.partial|*.crdownload" | |
| monitor_interval = "300" | |
| threads = "$THREADS" | |
| EOF | |
| chmod 700 "$CONFIG_DIR" | |
| chmod 600 "$CONFIG_FILE" | |
| } | |
| install_safe_service() { | |
| mkdir -p "$SERVICE_DIR" | |
| cat > "$SERVICE_FILE" <<EOF | |
| [Unit] | |
| Description=OneDrive Safe Idle Service | |
| After=network-online.target | |
| [Service] | |
| Type=oneshot | |
| ExecStart=/usr/bin/true | |
| RemainAfterExit=yes | |
| [Install] | |
| WantedBy=default.target | |
| EOF | |
| systemctl --user daemon-reload | |
| systemctl --user enable "$SERVICE_NAME" | |
| } | |
| install_wrapper() { | |
| mkdir -p "$HOME/.local/bin" | |
| cat > "$WRAPPER" <<'EOF' | |
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| REAL_BIN="/usr/bin/onedrive" | |
| CONFIG_DIR="$HOME/.config/onedrive" | |
| CONFIG_FILE="$CONFIG_DIR/config" | |
| SYNC_DIR="$HOME/OneDrive" | |
| SERVICE_NAME="onedrive-safe.service" | |
| help() { | |
| cat <<HELP | |
| OneDrive Safe Manager | |
| Usage: | |
| onedrive --help | |
| onedrive --status | |
| onedrive --login | |
| onedrive --download-only | |
| onedrive --syncall | |
| onedrive --dry-run | |
| onedrive --enable | |
| onedrive --disable | |
| onedrive --service-status | |
| onedrive --real-help | |
| Default: | |
| download-only configuration. | |
| Guarantees: | |
| --login does not sync. | |
| --login does not download. | |
| --login does not upload. | |
| The service is a safe idle no-op service. | |
| Manual commands: | |
| onedrive --login Re-authorize only. | |
| onedrive --download-only Manual cloud-to-local download. | |
| onedrive --syncall Manual bidirectional sync with confirmation. | |
| HELP | |
| } | |
| set_config_value() { | |
| local key="$1" | |
| local value="$2" | |
| mkdir -p "$CONFIG_DIR" "$SYNC_DIR" | |
| [[ -f "$CONFIG_FILE" ]] || touch "$CONFIG_FILE" | |
| tmp_file="$(mktemp)" | |
| awk -v k="$key" -v v="$value" ' | |
| BEGIN { replaced=0 } | |
| $0 ~ "^[[:space:]]*" k "[[:space:]]*=" { | |
| print k " = \"" v "\"" | |
| replaced=1 | |
| next | |
| } | |
| { print } | |
| END { | |
| if (replaced == 0) print k " = \"" v "\"" | |
| } | |
| ' "$CONFIG_FILE" > "$tmp_file" | |
| mv "$tmp_file" "$CONFIG_FILE" | |
| } | |
| remove_config_key() { | |
| local key="$1" | |
| [[ -f "$CONFIG_FILE" ]] || return 0 | |
| tmp_file="$(mktemp)" | |
| awk -v k="$key" ' | |
| $0 ~ "^[[:space:]]*" k "[[:space:]]*=" { next } | |
| { print } | |
| ' "$CONFIG_FILE" > "$tmp_file" | |
| mv "$tmp_file" "$CONFIG_FILE" | |
| } | |
| set_download_only_config() { | |
| set_config_value "sync_dir" "$SYNC_DIR" | |
| set_config_value "download_only" "true" | |
| set_config_value "upload_only" "false" | |
| set_config_value "remove_source_files" "false" | |
| set_config_value "skip_symlinks" "true" | |
| set_config_value "skip_file" "~*|.~*|*.tmp|*.swp|*.partial|*.crdownload" | |
| set_config_value "monitor_interval" "300" | |
| set_config_value "threads" "$(nproc 2>/dev/null || echo 2)" | |
| remove_config_key "no_remote_delete" | |
| chmod 700 "$CONFIG_DIR" | |
| chmod 600 "$CONFIG_FILE" | |
| } | |
| set_bidirectional_config() { | |
| set_config_value "sync_dir" "$SYNC_DIR" | |
| set_config_value "download_only" "false" | |
| set_config_value "upload_only" "false" | |
| set_config_value "remove_source_files" "false" | |
| set_config_value "skip_symlinks" "true" | |
| set_config_value "skip_file" "~*|.~*|*.tmp|*.swp|*.partial|*.crdownload" | |
| set_config_value "monitor_interval" "300" | |
| set_config_value "threads" "$(nproc 2>/dev/null || echo 2)" | |
| remove_config_key "no_remote_delete" | |
| chmod 700 "$CONFIG_DIR" | |
| chmod 600 "$CONFIG_FILE" | |
| } | |
| case "${1:-"--help"}" in | |
| --help|-h|help) | |
| help | |
| ;; | |
| --status|status) | |
| "$REAL_BIN" --confdir "$CONFIG_DIR" --display-config | |
| ;; | |
| --login|login) | |
| set_download_only_config | |
| echo "Starting Microsoft OneDrive authorization only." | |
| echo | |
| echo "This command will re-authorize the client." | |
| echo "It will not run --sync." | |
| echo "It will not run --monitor." | |
| echo "It will not run --download-only." | |
| echo "It will not run --dry-run." | |
| echo | |
| echo "Open the URL shown by the client, log in, approve access," | |
| echo "then paste the final response URL back into this terminal." | |
| echo | |
| "$REAL_BIN" --confdir "$CONFIG_DIR" --reauth | |
| set_download_only_config | |
| echo | |
| echo "Authorization completed." | |
| echo "Config remains download-only." | |
| echo "No sync/download/upload was executed." | |
| ;; | |
| --download-only|download-only) | |
| set_download_only_config | |
| echo "Manual download-only sync requested." | |
| echo "This may download cloud changes into:" | |
| echo " $SYNC_DIR" | |
| echo | |
| read -rp "Type DOWNLOAD to continue: " confirm | |
| if [[ "$confirm" != "DOWNLOAD" ]]; then | |
| echo "Cancelled." | |
| exit 1 | |
| fi | |
| "$REAL_BIN" --confdir "$CONFIG_DIR" --sync --download-only | |
| ;; | |
| --syncall|syncall) | |
| systemctl --user stop "$SERVICE_NAME" 2>/dev/null || true | |
| set_bidirectional_config | |
| echo "Manual bidirectional sync requested." | |
| echo "This can upload local changes from:" | |
| echo " $SYNC_DIR" | |
| echo | |
| read -rp "Type SYNC to continue: " confirm | |
| if [[ "$confirm" != "SYNC" ]]; then | |
| echo "Cancelled." | |
| set_download_only_config | |
| exit 1 | |
| fi | |
| "$REAL_BIN" --confdir "$CONFIG_DIR" --sync | |
| set_download_only_config | |
| echo | |
| echo "Manual sync completed." | |
| echo "Config restored to download-only." | |
| ;; | |
| --dry-run|dry-run) | |
| set_download_only_config | |
| echo "Manual dry-run requested." | |
| echo "This may contact OneDrive API and inspect metadata, but should not alter files." | |
| echo | |
| read -rp "Type DRYRUN to continue: " confirm | |
| if [[ "$confirm" != "DRYRUN" ]]; then | |
| echo "Cancelled." | |
| exit 1 | |
| fi | |
| "$REAL_BIN" --confdir "$CONFIG_DIR" --sync --download-only --dry-run | |
| ;; | |
| --enable|enable) | |
| systemctl --user enable "$SERVICE_NAME" | |
| echo "Safe idle service enabled. It does not sync." | |
| ;; | |
| --disable|disable) | |
| systemctl --user disable --now "$SERVICE_NAME" 2>/dev/null || true | |
| echo "Safe idle service disabled." | |
| ;; | |
| --service-status|service-status) | |
| systemctl --user status "$SERVICE_NAME" --no-pager | |
| ;; | |
| --real-help|real-help) | |
| "$REAL_BIN" --help | |
| ;; | |
| *) | |
| echo "Unknown command: $1" | |
| echo | |
| help | |
| exit 1 | |
| ;; | |
| esac | |
| EOF | |
| chmod +x "$WRAPPER" | |
| } | |
| ensure_path() { | |
| if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then | |
| grep -qF 'export PATH="$HOME/.local/bin:$PATH"' "$HOME/.bashrc" 2>/dev/null || \ | |
| echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.bashrc" | |
| export PATH="$HOME/.local/bin:$PATH" | |
| fi | |
| } | |
| disable_old_services() { | |
| systemctl --user disable --now onedrive.service 2>/dev/null || true | |
| systemctl --user disable --now onedrive-managed.service 2>/dev/null || true | |
| } | |
| main() { | |
| disable_old_services | |
| install_onedrive | |
| write_safe_config | |
| install_safe_service | |
| install_wrapper | |
| ensure_path | |
| echo | |
| echo "OneDrive safe setup complete." | |
| echo | |
| echo "Nothing was synced." | |
| echo "Nothing was downloaded." | |
| echo "Nothing was uploaded." | |
| echo "Folder preserved:" | |
| echo " $SYNC_DIR" | |
| echo | |
| echo "Use:" | |
| echo " source ~/.bashrc" | |
| echo " hash -r" | |
| echo " onedrive --login" | |
| echo " onedrive --status" | |
| echo | |
| echo "Manual actions only:" | |
| echo " onedrive --download-only" | |
| echo " onedrive --syncall" | |
| } | |
| main "$@" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| REAL_BIN="/usr/bin/onedrive" | |
| WRAPPER="$HOME/.local/bin/onedrive" | |
| CONFIG_DIR="$HOME/.config/onedrive" | |
| CONFIG_FILE="$CONFIG_DIR/config" | |
| SYNC_DIR="$HOME/OneDrive" | |
| SERVICE_DIR="$HOME/.config/systemd/user" | |
| SERVICE_FILE="$SERVICE_DIR/onedrive-safe.service" | |
| SERVICE_NAME="onedrive-safe.service" | |
| install_onedrive() { | |
| if [[ -x "$REAL_BIN" ]]; then | |
| echo "Using existing OneDrive client: $REAL_BIN" | |
| return 0 | |
| fi | |
| if command -v pacman >/dev/null 2>&1; then | |
| sudo pacman -S --needed git base-devel curl | |
| if command -v yay >/dev/null 2>&1; then | |
| yay -S --needed onedrive-abraunegg | |
| elif command -v paru >/dev/null 2>&1; then | |
| paru -S --needed onedrive-abraunegg | |
| else | |
| echo "Missing AUR helper: yay or paru." | |
| exit 1 | |
| fi | |
| elif command -v apt >/dev/null 2>&1; then | |
| sudo apt update | |
| sudo apt install -y onedrive | |
| elif command -v dnf >/dev/null 2>&1; then | |
| sudo dnf install -y onedrive | |
| else | |
| echo "Unsupported package manager." | |
| exit 1 | |
| fi | |
| } | |
| write_safe_config() { | |
| mkdir -p "$CONFIG_DIR" "$SYNC_DIR" | |
| THREADS="$(nproc 2>/dev/null || echo 2)" | |
| cat > "$CONFIG_FILE" <<EOF | |
| sync_dir = "$SYNC_DIR" | |
| download_only = "true" | |
| upload_only = "false" | |
| remove_source_files = "false" | |
| skip_symlinks = "true" | |
| skip_file = "~*|.~*|*.tmp|*.swp|*.partial|*.crdownload" | |
| monitor_interval = "300" | |
| threads = "$THREADS" | |
| EOF | |
| chmod 700 "$CONFIG_DIR" | |
| chmod 600 "$CONFIG_FILE" | |
| } | |
| install_safe_service() { | |
| mkdir -p "$SERVICE_DIR" | |
| cat > "$SERVICE_FILE" <<EOF | |
| [Unit] | |
| Description=OneDrive Safe Idle Service | |
| After=network-online.target | |
| [Service] | |
| Type=oneshot | |
| ExecStart=/usr/bin/true | |
| RemainAfterExit=yes | |
| [Install] | |
| WantedBy=default.target | |
| EOF | |
| systemctl --user daemon-reload | |
| systemctl --user enable "$SERVICE_NAME" | |
| } | |
| install_wrapper() { | |
| mkdir -p "$HOME/.local/bin" | |
| cat > "$WRAPPER" <<'EOF' | |
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| REAL_BIN="/usr/bin/onedrive" | |
| CONFIG_DIR="$HOME/.config/onedrive" | |
| CONFIG_FILE="$CONFIG_DIR/config" | |
| SYNC_DIR="$HOME/OneDrive" | |
| SERVICE_NAME="onedrive-safe.service" | |
| help() { | |
| cat <<HELP | |
| OneDrive Safe Manager | |
| Usage: | |
| onedrive --help | |
| onedrive --status | |
| onedrive --service | |
| onedrive --service-status | |
| onedrive --login | |
| onedrive --download-only | |
| onedrive --syncall | |
| onedrive --dry-run | |
| onedrive --enable | |
| onedrive --disable | |
| onedrive --real-help | |
| Default: | |
| download-only configuration. | |
| Guarantees: | |
| --login does not sync. | |
| --login does not download. | |
| --login does not upload. | |
| The service is a safe idle no-op service. | |
| Manual commands: | |
| onedrive --login Re-authorize only. | |
| onedrive --download-only Manual cloud-to-local download. | |
| onedrive --syncall Manual bidirectional sync with confirmation. | |
| HELP | |
| } | |
| set_config_value() { | |
| local key="$1" | |
| local value="$2" | |
| mkdir -p "$CONFIG_DIR" "$SYNC_DIR" | |
| [[ -f "$CONFIG_FILE" ]] || touch "$CONFIG_FILE" | |
| tmp_file="$(mktemp)" | |
| awk -v k="$key" -v v="$value" ' | |
| BEGIN { replaced=0 } | |
| $0 ~ "^[[:space:]]*" k "[[:space:]]*=" { | |
| print k " = \"" v "\"" | |
| replaced=1 | |
| next | |
| } | |
| { print } | |
| END { | |
| if (replaced == 0) print k " = \"" v "\"" | |
| } | |
| ' "$CONFIG_FILE" > "$tmp_file" | |
| mv "$tmp_file" "$CONFIG_FILE" | |
| } | |
| remove_config_key() { | |
| local key="$1" | |
| [[ -f "$CONFIG_FILE" ]] || return 0 | |
| tmp_file="$(mktemp)" | |
| awk -v k="$key" ' | |
| $0 ~ "^[[:space:]]*" k "[[:space:]]*=" { next } | |
| { print } | |
| ' "$CONFIG_FILE" > "$tmp_file" | |
| mv "$tmp_file" "$CONFIG_FILE" | |
| } | |
| set_download_only_config() { | |
| set_config_value "sync_dir" "$SYNC_DIR" | |
| set_config_value "download_only" "true" | |
| set_config_value "upload_only" "false" | |
| set_config_value "remove_source_files" "false" | |
| set_config_value "skip_symlinks" "true" | |
| set_config_value "skip_file" "~*|.~*|*.tmp|*.swp|*.partial|*.crdownload" | |
| set_config_value "monitor_interval" "300" | |
| set_config_value "threads" "$(nproc 2>/dev/null || echo 2)" | |
| remove_config_key "no_remote_delete" | |
| chmod 700 "$CONFIG_DIR" | |
| chmod 600 "$CONFIG_FILE" | |
| } | |
| set_bidirectional_config() { | |
| set_config_value "sync_dir" "$SYNC_DIR" | |
| set_config_value "download_only" "false" | |
| set_config_value "upload_only" "false" | |
| set_config_value "remove_source_files" "false" | |
| set_config_value "skip_symlinks" "true" | |
| set_config_value "skip_file" "~*|.~*|*.tmp|*.swp|*.partial|*.crdownload" | |
| set_config_value "monitor_interval" "300" | |
| set_config_value "threads" "$(nproc 2>/dev/null || echo 2)" | |
| remove_config_key "no_remote_delete" | |
| chmod 700 "$CONFIG_DIR" | |
| chmod 600 "$CONFIG_FILE" | |
| } | |
| case "${1:-"--help"}" in | |
| --help|-h|help) | |
| help | |
| ;; | |
| --status|status) | |
| "$REAL_BIN" --confdir "$CONFIG_DIR" --display-config | |
| ;; | |
| --service|service) | |
| echo "OneDrive Safe Service" | |
| echo | |
| echo -n "Enabled: " | |
| systemctl --user is-enabled "$SERVICE_NAME" 2>/dev/null || true | |
| echo -n "Active: " | |
| systemctl --user is-active "$SERVICE_NAME" 2>/dev/null || true | |
| echo | |
| systemctl --user status "$SERVICE_NAME" --no-pager | |
| ;; | |
| --service-status|service-status) | |
| systemctl --user status "$SERVICE_NAME" --no-pager | |
| ;; | |
| --login|login) | |
| set_download_only_config | |
| echo "Starting Microsoft OneDrive authorization only." | |
| echo | |
| echo "Open the URL shown by the client, log in, approve access," | |
| echo "then paste the final response URL back into this terminal." | |
| echo | |
| echo "No sync/download/upload will be executed." | |
| echo | |
| "$REAL_BIN" --confdir "$CONFIG_DIR" --reauth | |
| set_download_only_config | |
| echo | |
| echo "Authorization completed." | |
| echo "Config remains download-only." | |
| ;; | |
| --download-only|download-only) | |
| set_download_only_config | |
| echo "Manual download-only sync requested." | |
| echo "This may download cloud changes into:" | |
| echo " $SYNC_DIR" | |
| echo | |
| read -rp "Type DOWNLOAD to continue: " confirm | |
| [[ "$confirm" == "DOWNLOAD" ]] || { | |
| echo "Cancelled." | |
| exit 1 | |
| } | |
| "$REAL_BIN" --confdir "$CONFIG_DIR" --sync --download-only | |
| ;; | |
| --syncall|syncall) | |
| systemctl --user stop "$SERVICE_NAME" 2>/dev/null || true | |
| set_bidirectional_config | |
| echo "Manual bidirectional sync requested." | |
| echo "This can upload local changes from:" | |
| echo " $SYNC_DIR" | |
| echo | |
| read -rp "Type SYNC to continue: " confirm | |
| if [[ "$confirm" != "SYNC" ]]; then | |
| echo "Cancelled." | |
| set_download_only_config | |
| exit 1 | |
| fi | |
| "$REAL_BIN" --confdir "$CONFIG_DIR" --sync | |
| set_download_only_config | |
| echo | |
| echo "Manual sync completed." | |
| echo "Config restored to download-only." | |
| ;; | |
| --dry-run|dry-run) | |
| set_download_only_config | |
| echo "Manual dry-run requested." | |
| echo "This may contact OneDrive API and inspect metadata, but should not alter files." | |
| echo | |
| read -rp "Type DRYRUN to continue: " confirm | |
| [[ "$confirm" == "DRYRUN" ]] || { | |
| echo "Cancelled." | |
| exit 1 | |
| } | |
| "$REAL_BIN" --confdir "$CONFIG_DIR" --sync --download-only --dry-run | |
| ;; | |
| --enable|enable) | |
| systemctl --user enable "$SERVICE_NAME" | |
| echo "Safe idle service enabled. It does not sync." | |
| ;; | |
| --disable|disable) | |
| systemctl --user disable --now "$SERVICE_NAME" 2>/dev/null || true | |
| echo "Safe idle service disabled." | |
| ;; | |
| --real-help|real-help) | |
| "$REAL_BIN" --help | |
| ;; | |
| *) | |
| echo "Unknown command: $1" | |
| echo | |
| help | |
| exit 1 | |
| ;; | |
| esac | |
| EOF | |
| chmod +x "$WRAPPER" | |
| } | |
| ensure_path() { | |
| if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then | |
| grep -qF 'export PATH="$HOME/.local/bin:$PATH"' "$HOME/.bashrc" 2>/dev/null || \ | |
| echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.bashrc" | |
| export PATH="$HOME/.local/bin:$PATH" | |
| fi | |
| } | |
| disable_old_services() { | |
| systemctl --user disable --now onedrive.service 2>/dev/null || true | |
| systemctl --user disable --now onedrive-managed.service 2>/dev/null || true | |
| } | |
| main() { | |
| disable_old_services | |
| install_onedrive | |
| write_safe_config | |
| install_safe_service | |
| install_wrapper | |
| ensure_path | |
| echo | |
| echo "OneDrive safe setup complete." | |
| echo "Nothing was synced, downloaded, or uploaded." | |
| echo | |
| echo "Folder preserved:" | |
| echo " $SYNC_DIR" | |
| echo | |
| echo "Use:" | |
| echo " source ~/.bashrc" | |
| echo " hash -r" | |
| echo " onedrive --service" | |
| echo " onedrive --login" | |
| echo " onedrive --status" | |
| } | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment