-
-
Save zealinux/64b4ccb8d0263bba3e89a57f1d07cd64 to your computer and use it in GitHub Desktop.
"Shebang" function for Zsh
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
# shebang [-iv] [-t interpreter] [-I extension] [-J [extension]] [filename] | |
# | |
# If no filename is given, print a shebang. If a filename is given, append a shebang to the file and print its contents. If a filename is given and the -I or -J options are specified, append a shebang to the file in place. | |
# | |
# OPTIONS | |
# -i | |
# Interactive mode; ask for confirmation first. | |
# -I | |
# Modify "filename" in place (as in `sed -i`) using specified extension. Extension is mandatory. | |
# -J | |
# Same as -I, but extension is mandatory only if the string "gsed" cannot be found in the output of `which sed`. Overridden by -I. | |
# -t | |
# Specify an interpreter, e.g. `shebang -t zsh` produces "#!/usr/bin/env zsh" | |
# -v | |
# Print (to stderr) the interpreter being used. | |
shebang () { | |
local interpreter | |
local inplace | |
local inplace2 | |
local verbose | |
local interactive | |
local input_shebang | |
local shebang | |
local continue | |
local sed_command | |
local gsed_avail | |
zparseopts -D t:=interpreter I:=inplace J::=inplace2 v=verbose -i=interactive | |
(( $? )) && return 1 | |
if [[ -n $1 ]]; then | |
input_shebang=$(sed -n '1 { /^#!/ p; }' "$1") | |
if (( $? )); then | |
echo "Unable to read $1." >&2 | |
return 1 | |
fi | |
if [[ -n "$input_shebang" ]]; then | |
echo "$1 already has a shebang." >&2 | |
return 1 | |
fi | |
fi | |
if [[ (-z "$interpreter") && (-z "$1") ]]; then | |
echo "The -t option is mandatory if no argument is supplied." >&2 | |
return 1 | |
fi | |
if [[ (-z "$interpreter") && (-n "$1") ]]; then | |
interpreter=$(filename=$(basename "$1"); [[ "$filename" = *.* ]] && echo "${filename##*.}" || echo '') # grab extension | |
interpreter=${interpreter:#(* *|* | *)} # "extensions" with whitespace probably aren't legit | |
interpreter=${interpreter:-sh} # assume sh if no extension and no -t option | |
else | |
interpreter="$interpreter[2]" | |
fi | |
shebang="#!/usr/bin/env $interpreter" | |
if [[ -n $verbose ]]; then | |
echo "Using interpreter '$interpreter'" >&2 | |
fi | |
if [[ -n $interactive ]]; then | |
read -q "continue?Shebang will be '$shebang'. Ok? y/n: " | |
[[ $continue == n ]] && return 1 | |
fi | |
if [[ -z "$1" ]]; then | |
echo $shebang | |
else | |
gsed_avail=$(command which -s gsed && echo 1) | |
echo $gsed_avail | |
if [[ -n $gsed_avail ]]; then | |
sed_command="1 i\\$shebang\n" | |
if [[ -n $inplace ]]; then | |
gsed "${inplace/-I/-i}" "$sed_command" "$1" | |
elif [[ -n $inplace2 ]]; then | |
gsed "${inplace2/-J/-i}" "$sed_command" "$1" | |
else | |
gsed "$sed_command" "$1" | |
fi | |
else | |
sed_command='1 i\ | |
REPLACEME\n' # need to use single quotes to preserve the line break | |
sed_command=${sed_command/REPLACEME/$shebang} # work around the single quotes | |
if [[ -n $inplace ]]; then | |
sed "${inplace/-I/-i}" "$sed_command" "$1" | |
elif [[ (-n $inplace2) && (-z ${inplace2#-J}) ]]; then | |
echo "'-J' was given without an argument, but 'gsed' is unavailable. Specify an explicit extension or use -I." | |
elif [[ -n ${inplace2#-J} ]]; then | |
sed "${inplace2/-J/-i}" "$sed_command" "$1" | |
else | |
sed "$sed_command" "$1" | |
fi | |
fi | |
fi | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment