Skip to content

Instantly share code, notes, and snippets.

@BlakeHancock
Last active October 17, 2021 21:14
Show Gist options
  • Save BlakeHancock/b49c6ba6145f560bb2d70835afc15b25 to your computer and use it in GitHub Desktop.
Save BlakeHancock/b49c6ba6145f560bb2d70835afc15b25 to your computer and use it in GitHub Desktop.
Project SSH Upload Script
#!/bin/env bash
err_report() {
echo "Error on line $1."
}
err_exit() {
echo "${SCRIPT_NAME}: ${1:-"Unknown error."}" 1>&2
exit 1
}
SCRIPT_NAME="$(basename "$0")"
PARSED_ARGUMENTS=$( \
getopt \
--name "${SCRIPT_NAME%.*}" \
--quiet \
--options ds:L \
--longoptions dev,suffix:,dereference \
-- "$@" \
)
FIND_FILENAME=".${SCRIPT_NAME%.*}rc"
trap 'err_report $LINENO' ERR
eval set -- "$PARSED_ARGUMENTS"
suffix=
cur_dir=
src_dir=
src_filename=
dest_dir=
follow_symlinks=false
while [ "$1" != "" ]; do
case $1 in
-d | --dev)
# Standard dev suffix
suffix="_dev"
shift
;;
-s | --suffix)
# Custom suffix
suffix="_$2"
shift 2
;;
-L | --dereference)
follow_symlinks=true
shift
;;
-- )
# File or directory to upload
if [ -f "$2" ]; then
src_dir=$(dirname -- "$2")
src_filename=$(basename -- "$2")
cur_dir=$src_dir
else
src_dir=$2
cur_dir=$2
fi
shift 2
;;
* )
err_exit "Invalid argument. ($1)"
;;
esac
done
# If suffix provided, ensure it is valid
if [[ -n "$suffix" ]] && [[ ! "$suffix" =~ ^[0-9a-z_]+$ ]]; then
err_exit "Invalid suffix."
fi
# Find parent directory with .rc file
while [[ $cur_dir != / ]]; do
if [ -f "$cur_dir/$FIND_FILENAME" ]; then
break
fi
if [ "$follow_symlinks" = true ]; then
cur_dir="$(readlink -f "$cur_dir"/..)"
else
cur_dir="$(realpath -s "$cur_dir"/..)"
fi
done
if [[ $cur_dir == / ]]; then
err_exit "$FIND_FILENAME file not found."
fi
source "$cur_dir/$FIND_FILENAME"
# Override non suffixed values with provided suffixed variants
if [[ -n "$suffix" ]]; then
if [[ -v local_dir$suffix ]]; then
local_dir=$(eval echo \$local_dir"$suffix")
fi
if [[ -v remote_dir$suffix ]]; then
remote_dir=$(eval echo \$remote_dir"$suffix")
fi
if [[ -v remote_host$suffix ]]; then
remote_host=$(eval echo \$remote_host"$suffix")
fi
if [[ -v remote_username$suffix ]]; then
remote_username=$(eval echo \$remote_username"$suffix")
fi
if [[ -v remote_key$suffix ]]; then
remote_key=$(eval echo \$remote_key"$suffix")
fi
fi
# If local dir is set, modify current dir accordingly
if [[ -n "$local_dir" ]]; then
if [[ $local_dir == ./* ]]; then
# Append relative path
cur_dir="$(realpath -s "$cur_dir"/"$local_dir")"
else
cur_dir=$local_dir
fi
fi
# If source directory does not start with the current
# directory, then don't upload
if [ "$src_dir" = "${src_dir#"$cur_dir"}" ]; then
err_exit "Source directory lies outside local directory."
fi
dest_dir=$remote_dir
# Add /./ so rsync --relative will create non existing directories
rsrc_dir="${cur_dir}/.${src_dir#"$cur_dir"}"
# Setup SSH call
rsh="ssh"
if [[ -z "$remote_key" ]]; then
rsh="$rsh -i $remote_key"
fi
upload_file() {
#--compress \
rsync \
--recursive \
--perms \
--times \
--verbose \
--relative \
--rsh="$rsh" \
"$2/$3" \
"$remote_username@$remote_host:$1"
}
if [[ -n "$src_filename" ]]; then
# Single file upload
upload_file "$dest_dir" "$rsrc_dir" "$src_filename"
else
# Directory upload (including .files)
for src_filename in "$src_dir"/{.,}*; do
src_filename=$(basename -- "$src_filename")
if [ "$src_filename" = "." ] || [ "$src_filename" = ".." ]; then
continue
fi
upload_file "$dest_dir" "$rsrc_dir" "$src_filename"
done
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment