Back to blog
Jun 2019·1 min readAI-translated

Autopush - Simply Upload Changed Files

#auf-server-hochladen#auto-upload#automatisch-hochladen#autopush-to-server#autoupload#dateien-aktualisieren#hochladen#upload#upload-to-server

To simplify my web design / web development workflow, I wrote myself a small autopush script. The script watches a given folder and all its subfolders for changes and uploads the changed files to a remote server via SCP. So if you like to develop locally but want to push your changes straight to your server without constantly uploading manually, you'll probably like this script :) As always: no liability for damages.

Important:

  1. You need to authenticate against the server with an SSH key, otherwise the bash script needs minimal adjustments.
  2. You need to have fswatch installed.

Autopush works like this: you create an autopush config file in ini format, which is passed to the bash script as the first parameter. The autopush file is structured as follows:

  • remote_host= The host you want to push the files to. Can be a domain or an IP. Remember the SSH keys.
  • remote_username= The username you authenticate with on the server
  • remote_mapping= The path that is mapped to. Changes in local_source are uploaded relative to remote_mapping.
  • local_source= The local path that is to be watched and pushed.
  • exclude=source,_Server Files that shouldn't be pushed and are excluded from watching.

Note: .DS_Store files are excluded programmatically and don't need to be listed explicitly.

The folder in local_source is watched by the script. As soon as a file in it changes, it is uploaded to the server via

scp local_file_path remote_username@remote_host:/remote_mapping/absolute_local_path

You can call the bash script simply via:

autopush.sh /path/to/config.ini

And here is the complete script:

#!/bin/sh
if [ $# -eq 1 ]; then
    CONFIGFILE=$1
    . $1
    echo "Autopushing '$local_source' now..."
    /usr/local/bin/fswatch -0 "$local_source" | xargs -0 -n 1 sh $0 0 $CONFIGFILE
elif [ $# -eq 2 ] && [ $2="--fullsync" ]; then
    CONFIGFILE=$1
    . $1
    echo "Fullsyncing '$local_source' now..."
    scp -r $local_source/* $remote_username@$remote_host:$remote_mapping
else
    CONFIGFILE=$2
    FILE=$3
    . $CONFIGFILE
    length_local_source=${#local_source}
    length_changed_file_absolute=${#FILE}
    length_changed_file_relative=$((0-length_local_source-length_changed_file_absolute))
    relative_path=${FILE:$length_local_source}
    donotpush=(${exclude//,/ })
    donotpush+=($CONFIGFILE)
    donotpush+=(".DS_Store")
    for i in "${donotpush[@]}"
    do
        if [[ $FILE == *$i* ]]; then
            echo "[STOP] DO NOT PUSH $FILE (MATCHES '$i')"
            exit
        fi
    done
    remote_target="$remote_mapping$relative_path"
    if [ -d "$FILE" ] || [ -f "$FILE" ]; then
        echo "[CHANGE] `date '+%Y-%m-%d %H:%M:%S'` $relative_path -> $remote_target";
        scp -r $FILE $remote_username@$remote_host:$remote_target
    else
        echo "[DELETE] rm -rf $remote_target";
        ssh $remote_username@$remote_host "rm -rf $remote_target"
    fi
fi
NewerBrand-New MacBook Just Shuts Itself OffOlderCentOS - Server Essentials