Skip to content

Instantly share code, notes, and snippets.

@jhyland87
Last active May 16, 2017 19:06
Show Gist options
  • Save jhyland87/bee38756941448c77ef45fb108651c4f to your computer and use it in GitHub Desktop.
Save jhyland87/bee38756941448c77ef45fb108651c4f to your computer and use it in GitHub Desktop.
A more improved version of the shebang script
#!/usr/local/bin/bash4
function stderr {
echo $@ 1>&2
[[ -z $2 ]] && exit 1
}
function abspath {
[[ -d $1 ]] && { cd "$1"; echo "$(pwd -P)"; } ||
{ cd "$(dirname "$1")"; echo "$(pwd -P)/$(basename "$1")"; }
}
which bash4 >/dev/null
[[ $? -ne 0 ]] && stderr "You need bash4 to use this beauty..."
declare -A cfg
declare -A editors
declare -A argvals
declare -A script
declare -A ext_aliases
ext_aliases['pl']="perl"
ext_aliases['js']="node"
ext_aliases['py']="python"
# Set Defaults
cfg['default_editor']="vim"
argvals['author']="$(whoami)"
# The editors should be the full command used to open a file
# Replacement Strings:
# %script% - Replaced with scripts absolute path
# %wc-l% - Replaced with the scripts line count
editors['subl']="/Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl --add %script%:%wc-l%"
editors['atom']="/Applications/Atom.app/Contents/MacOS/Atom --add %script%:%wc-l%"
editors['vim']="/usr/bin/vim +%wc-l% %script%"
editors['vi']="/usr/bin/vi +%wc-l% %script%"
editors['nano']="/usr/bin/nano +%wc-l% %script%"
#Set Script Name variable
SCRIPT=`basename ${BASH_SOURCE[0]}`
#Set fonts for Help.
NORM=`tput sgr0`
BOLD=`tput bold`
REV=`tput smso`
#Help function
function HELP {
fmt=" ${BOLD}%-5s${NORM} %s\n"
echo -e \\n"Help documentation for ${BOLD}${SCRIPT}.${NORM}"\\n
echo -e "${REV}Basic usage:${NORM} ${BOLD}./$SCRIPT -b bash4 script.sh${NORM}"\\n
echo "Command to easily and quickly create executable scripts."
printf "${fmt}" "-a" "Sets the ${BOLD}author${NORM} of the script. Defaults to $(whoami)."
printf "${fmt}" "-b" "Sets the ${BOLD}binary${NORM} to be used for the executable."
printf "${fmt}" "-e" "Sets the ${BOLD}editor${NORM} to open the script in."
printf "${fmt}" "-c" "Add any extra ${BOLD}comments${NORM} to the docblock header."
printf "${fmt}" "-d" "A brief ${BOLD}description${NORM} of the script to add to the docblock header."
printf "${fmt}" "-p" "Sets the scripts ${BOLD}permissions${NORM}. Default is ${BOLD}+x${NORM}."
printf "${fmt}" "-f" "Will ${BOLD}force${NORM} the deletion of an existing script with the same name."
printf "${fmt}" "-v" "Displays a more ${BOLD}verbose${NORM} output."
printf "${fmt}" "-h" "Displays this ${BOLD}help${NORM} message. No further functions are performed."
echo -e "\nExamples:"
echo -e "\t${BOLD}./$SCRIPT -e vi somescript.bash${NORM}"
echo -e "\t${BOLD}./$SCRIPT -e atom -b bash4 some_bashscript${NORM}"
echo -e "\t${BOLD}./$SCRIPT -e subl -b perl -a \"John Doe\" -s hello_world.pl${NORM}"
echo -e "\t${BOLD}./$SCRIPT -e subl -d \"Description of this perl script\" -b python -c \"Extra comments for header\" -f hello_world.py${NORM}"
exit 1
}
#Check the number of arguments. If none are passed, print help and exit.
NUMARGS=$#
#echo -e \\n"Number of arguments: $NUMARGS"
if [ $NUMARGS -eq 0 ]; then
HELP
fi
while getopts :e:b:c:d:p:s:a:hfv FLAG; do
case $FLAG in
e)
argvals['editor']="${OPTARG}"
;;
a)
argvals['author']="${OPTARG}"
;;
b)
argvals['binary']="${OPTARG}"
;;
s)
script['provided']="${OPTARG}"
;;
c)
argvals['comments']="${OPTARG}"
;;
d)
argvals['description']="${OPTARG}"
;;
p)
argvals['perms']="${OPTARG}"
;;
f)
argvals['force']=1
;;
v)
argvals['verbose']=1
;;
h)
HELP
;;
\?)
echo -e \\n"Option -${BOLD}$OPTARG${NORM} not allowed."
HELP
;;
esac
done
shift $((OPTIND-1)) #This tells getopts to move on to the next argument.
### End getopts code ###
### Main loop to process files ###
#This is where your main file processing will take place. This example is just
#printing the files and extensions to the terminal. You should place any other
#file processing tasks within the while-do loop.
while [ $# -ne 0 ]; do
FILE=$1
script['provided']="${1}"
shift #Move on to next input file.
done
if ! test "${script['provided']}"
then
echo "No script name provided"
exit 1
fi
# Get the absolute path to the script provided
script['abspath']=$(abspath "${script['provided']}")
# Get the basename (script name without path)
script['basename']=$(basename "${script['abspath']}")
# The directory holding the script
script['dirname']=$(dirname "${script['abspath']}")
[[ "${script['basename']%.*}" -ne "${script['extension']}" ]] && script['noext']="${script['basename']%.*}"
# Only save the extension if there is one
[[ "${script['basename']##*.}" != "${script['basename']}" ]] && script['extension']="${script['basename']##*.}"
if test "${argvals['verbose']}"
then
### End main loop ###
fmt="%-13s : ${BOLD}%s${NORM}\n"
test "${script['basename']}" && printf "${fmt}" "Script" "${script['basename']}"
test "${script['extension']}" && printf "${fmt}" "Extension" "${script['extension']}"
test "${script['dirname']}" && printf "${fmt}" "Directory" "${script['dirname']}"
test "${script['abspath']}" && printf "${fmt}" "Absolute" "${script['abspath']}"
test "${script['noext']}" && printf "${fmt}" "NoExt" "${script['noext']}"
test "${argvals['author']}" && printf "${fmt}" "Author" "${argvals['author']}"
test "${argvals['editor']}" && printf "${fmt}" "Editor" "${argvals['editor']}"
test "${argvals['perms']}" && printf "${fmt}" "Permissions" "${argvals['perms']}"
test "${argvals['binary']}" && printf "${fmt}" "Executable" "${argvals['binary']}"
test "${argvals['comments']}" && printf "${fmt}" "Comments" "${argvals['comments']}"
test "${argvals['description']}" && printf "${fmt}" "Description" "${argvals['description']}"
test "${argvals['force']}" && printf "${fmt}" "Force" "${argvals['force']}"
test "${argvals['verbose']}" && printf "${fmt}" "Verbose" "${argvals['verbose']}"
fi
# FILE CREATION
# If the script exists, well either exit, or overwrite
if [[ -a "${script['abspath']}" ]]
then
# If -f isnt set, then exit
[[ -z "${argvals['force']}" ]] && stderr "The script name provided already exists - Either delete it, or add -f to forcefully overwrite the script."
# -f is set, overwrite it
> "${script['abspath']}"
[[ $? -ne 0 ]] && stderr "Failed to overwrite the existing script at ${script['abspath']}"
# Script doesnt exist - create it
else
touch "${script['abspath']}"
[[ $? -ne 0 ]] && stderr "Failed to create a script at ${script['abspath']}"
fi
# PERMISSIONS
if test "${argvals['perms']}"
then
chmod_val="${argvals['perms']}"
else
chmod_val="+x"
fi
eval "chmod ${chmod_val} ${script['abspath']}"
[[ $? -ne 0 ]] && stderr "Failed to chmod {chmod_val} the script at ${script['abspath']}"
if test "${argvals['binary']}"
then
bin="${argvals['binary']}"
elif test "${script['extension']}"
then
bin="${script['extension']}"
fi
if [[ -n $bin ]]
then
bin_path=$(which ${bin})
[[ $? -ne 0 ]] && stderr "Failed to locate a binary named $bin anywhere in your \$PATH ($PATH)"
echo -e "#! ${bin_path}\n" >> "${script['abspath']}"
fi
# SCRIPT COMMENTS/HEADER
docblock_format="# %-15s : %s\n"
printf "${docblock_format}" "Script" "${script['basename']}" >> "${script['abspath']}"
test "${argvals['description']}" && printf "${docblock_format}" "Description" "${argvals['description']}" >> "${script['abspath']}"
printf "${docblock_format}" "Author" "${argvals['author']}" >> "${script['abspath']}"
printf "${docblock_format}" "Created" $(date +%Y-%m-%d) >> "${script['abspath']}"
printf "${docblock_format}" "Directory" "${script['dirname']}" >> "${script['abspath']}"
test "${argvals['comments']}" && printf "${docblock_format}" "Comments" "${argvals['comments']}" >> "${script['abspath']}"
[[ -n $bin ]] && printf "${docblock_format}" "Executable" "${bin}" >> "${script['abspath']}"
echo -e "\n" >> "${script['abspath']}"
# OPENING EDITOR
script_wc=$(wc -l "${script['abspath']}" | awk '{print $1}')
script_wc=$(($script_wc+1))
if test "${argvals['editor']}"
then
open_with="${argvals['editor']}"
elif [[ -n ${VISUAL} ]] || [[ -n ${FCEDIT} ]] || [[ -n ${EDITOR} ]]
then
open_with="${FCEDIT:-${VISUAL:-${EDITOR:-vi}}}"
else
open_with="${cfg['default_editor']}"
fi
if test "${editors[$open_with]}"
then
cmd=$(echo "${editors[$open_with]}" | sed "s|%script%|${script['abspath']}|g")
cmd=$(echo "${cmd}" | sed "s|%wc-l%|${script_wc}|g")
#echo "Executing: ${cmd}"
#eval ${cmd}
else
cmd="${open_with} ${script['abspath']}"
fi
eval ${cmd}
[[ $? -ne 0 ]] && stderr "Failed to open the script with the editor ${open_with}"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment