I wrote a tiny shell script that basically installs a script into your system by copying it to someplace like /usr/local/bin
, chmodding it, and adding it to your PATH. It works on both Unix and Windows (via an emulation layer like MSys or Cygwin). Its source code is available on GitHub. Here is the script in its entirety:
#!/bin/sh
set -e
help()
{
echo 'sinister is a simple installer for shell scripts.'
echo
echo 'Usage: sinister -u url [options]'
echo
echo 'Options:'
echo
echo '-?,-h,--help: Print this help and exit.'
echo '-c,--chmod: The mode to chmod your script. Defaults are a+x and u+x.'
echo '-d,--debug: sinister should be run in debug mode.'
echo '-l,--local: The script should be saved for the current user, instead of the entire machine.'
echo '-n,--name: The name of the file the script should be saved to. Mandatory if no URL is given.'
echo '-o,--output: The output directory the script should be saved to.'
echo 'By default this is ~/bin on Unix systems, and C:\Users\you\AppData\Local\script on Windows.'
echo '-u,--url: The location of the script online. e.g: https://github.com/you/repo/raw/master/script'
echo 'If no URL is given the script is read from stdin.'
}
on_windows()
{
uname | grep -q '[CYGWIN|MINGW|MSYS]'
}
per_user()
{
test $LOCAL = 'true'
}
run_powershell()
{
powershell -NoProfile -ExecutionPolicy Bypass "$1"
}
getpath_windows()
{
run_powershell "[Environment]::GetEnvironmentVariable('PATH', '$1')"
}
setpath_windows()
{
run_powershell "[Environment]::SetEnvironmentVariable('PATH', '$1', '$2')"
}
pwd_windows()
{
run_powershell 'Get-Location'
}
CHMOD=
LOCAL='false'
NAME=
OUTPUT=
URL=
test $# -ne 0
while [ $# -gt 0 ]
do
case "$1" in
'-?'|-h|--help) help; exit 0 ;;
-c|--chmod) CHMOD="$2"; shift ;;
-d|--debug) set -x ;;
-l|--local) LOCAL='true' ;;
-n|--name) NAME="$2"; shift ;;
-o|--output) OUTPUT="$2"; shift ;;
-u|--url) URL="$2"; shift ;;
*) help; exit 1 ;;
esac
shift
done
if [ -z "$CHMOD" ]; then
if per_user; then
CHMOD='u+x' # Executable for the current user
else
CHMOD='a+x' # Executable for all users
fi
fi
if [ -z "$URL" ]; then
test ! -z "$NAME"
SCRIPT=$(< /dev/stdin) # read from standard input
else
NAME=${URL##*/} # Grab everything after the last /
if which curl > /dev/null 2>&1; then
SCRIPT=$(curl -sSL "$URL")
else # Assume wget is installed
SCRIPT=$(wget -q -O - "$URL")
fi
fi
if [ -z "$OUTPUT" ]; then
if per_user; then
if on_windows; then
OUTPUT=~/AppData/Local/"$NAME"
else
OUTPUT=~/bin
fi
else
if on_windows; then
OUTPUT='/C/Program Files/$NAME'
else
OUTPUT='/usr/local/bin'
fi
fi
fi
# Use sudo on Unix
! on_windows && SUDO='sudo'
# Where the magic happens
$SUDO mkdir -p "$OUTPUT"
cd "$OUTPUT"
echo "$SCRIPT" | $SUDO tee "$NAME" > /dev/null
$SUDO chmod $CHMOD "$NAME"
# Add $OUTPUT to PATH if it's not in it
if ! which "$NAME" > /dev/null 2>&1; then
if on_windows; then
if per_user; then
TARGET='User'
else
TARGET='Machine'
fi
CURRENT_PATH=$(getpath_windows $TARGET)
CURRENT_DIRECTORY=$(pwd_windows)
setpath_windows "$CURRENT_PATH;$CURRENT_DIRECTORY" $TARGET
else # Unix
CONTENTS="export PATH=\$PATH:$OUTPUT"
if per_user; then
echo "$CONTENTS" >> ~/.profile
else
sudo echo "$CONTENTS" >> /etc/profile
fi
fi
fi
Any feedback would be appreciated; I haven't tested this on Windows yet so some of the PowerShell snippets might be untested.