Skip to content

Instantly share code, notes, and snippets.

@leohacker
Last active July 20, 2016 16:19
Show Gist options
  • Save leohacker/5bc75cc6c0318863fece4c434d3fec91 to your computer and use it in GitHub Desktop.
Save leohacker/5bc75cc6c0318863fece4c434d3fec91 to your computer and use it in GitHub Desktop.
Bash Snippet

Advanced Bash Scripting Guide

Code snippet from ABS.

E_XCD=86 # Can't change directory?
# cd /var/log || {
# echo "Cannot change to necessary directory." >&2
# exit $E_XCD;
# }
case "$Keypress" in
[[:lower:]] ) echo "Lowercase letter";;
[[:upper:]] ) echo "Uppercase letter";;
[0-9] ) echo "Digit";;
* ) echo "Punctuation, whitespace, or other";;
esac # Allows ranges of characters in [square brackets],
#+ or POSIX ranges in [[double square brackets.
exit 0
# A zero return value from the script upon exit indicates success
#+ to the shell.
filename=$(basename "$fullfile")
extension=$([[ ${filename} == *.* ]] && echo "${filename##*.}" || echo "")
filename=$([[ ${filename} == *.* ]] && echo "${filename%.*}" || echo "${filename}")
a=letter_of_alphabet
letter_of_alphabet=z
echo "a = $a" # Direct reference.
echo "Now a = ${!a}" # Indirect reference.
# The ${!variable} notation is more intuitive than the old
#+ eval var1=\$$var2
# Old way
# varname=USER
# $varname == USER
# \$$varname == $USER in literal
# eval variable=..... evaluate and assign to variable
eval variable=\$$varname
#!/bin/bash
# getopt-simple.sh
# Author: Chris Morgan
# Used in the ABS Guide with permission.
getopt_simple()
{
echo "getopt_simple()"
echo "Parameters are '$*'"
until [ -z "$1" ]
do
echo "Processing parameter of: '$1'"
if [ ${1:0:1} = '/' ]
then
tmp=${1:1} # Strip off leading '/' . . .
parameter=${tmp%%=*} # Extract name.
value=${tmp##*=} # Extract value.
echo "Parameter: '$parameter', value: '$value'"
eval $parameter=$value
fi
shift
done
}
# Pass all options to getopt_simple().
getopt_simple $*
echo "test is '$test'"
echo "test2 is '$test2'"
exit 0 # See also, UseGetOpt.sh, a modified version of this script.
---
sh getopt_example.sh /test=value1 /test2=value2
Parameters are '/test=value1 /test2=value2'
Processing parameter of: '/test=value1'
Parameter: 'test', value: 'value1'
Processing parameter of: '/test2=value2'
Parameter: 'test2', value: 'value2'
test is 'value1'
test2 is 'value2'
#!/bin/bash
# Planets revisited.
# Associate the name of each planet with its distance from the sun.
for planet in "Mercury 36" "Venus 67" "Earth 93" "Mars 142" "Jupiter 483"
do
set -- $planet # Parses variable "planet"
#+ and sets positional parameters.
# The "--" prevents nasty surprises if $planet is null or
#+ begins with a dash.
# May need to save original positional parameters,
#+ since they get overwritten.
# One way of doing this is to use an array,
# original_params=("$@")
echo "$1 $2,000,000 miles from the sun"
#-------two tabs---concatenate zeroes onto parameter $2
done
# (Thanks, S.C., for additional clarification.)
exit 0
#!/bin/bash
filename="*txt"
for file in $filename
do
echo "Contents of $file"
echo "---"
cat "$file"
echo
done
#!/bin/bash
# revposparams.sh: Reverse positional parameters.
# Script by Dan Jacobson, with stylistic revisions by document author.
set a\ b c d\ e;
# ^ ^ Spaces escaped
# ^ ^ Spaces not escaped
OIFS=$IFS; IFS=:;
# ^ Saving old IFS and setting new one.
echo
until [ $# -eq 0 ]
do # Step through positional parameters.
echo "### k0 = "$k"" # Before
k=$1:$k; # Append each pos param to loop variable.
# ^
echo "### k = "$k"" # After
echo
shift;
done
set $k # Set new positional parameters.
echo -
echo $# # Count of positional parameters.
echo -
echo
for i # Omitting the "in list" sets the variable -- i --
#+ to the positional parameters.
do
echo $i # Display new positional parameters.
done
IFS=$OIFS # Restore IFS.
# Question:
# Is it necessary to set an new IFS, internal field separator,
#+ in order for this script to work properly?
# What happens if you don't? Try it.
# And, why use the new IFS -- a colon -- in line 17,
#+ to append to the loop variable?
# What is the purpose of this?
exit 0
$ ./revposparams.sh
### k0 =
### k = a b
### k0 = a b
### k = c a b
### k0 = c a b
### k = d e c a b
-
3
-
d e
c
a b
word=Linux
letter_sequence=inu
if echo "$word" | grep -q "$letter_sequence"
# The "-q" option to grep suppresses output.
then
echo "$letter_sequence found in $word"
else
echo "$letter_sequence not found in $word"
fi
# Usage ./myscript.sh -e conf -s /etc -l /usr/lib /etc/hosts
#!/bin/bash
# Use -gt 1 to consume two arguments per pass in the loop (e.g. each
# argument has a corresponding value to go with it).
# Use -gt 0 to consume one or more arguments per pass in the loop (e.g.
# some arguments don't have a corresponding value to go with it such
# as in the --default example).
# note: if this is set to -gt 0 the /etc/hosts part is not recognized ( may be a bug )
while [[ $# -gt 1 ]]
do
key="$1"
case $key in
-e|--extension)
EXTENSION="$2"
shift # past argument
;;
-s|--searchpath)
SEARCHPATH="$2"
shift # past argument
;;
-l|--lib)
LIBPATH="$2"
shift # past argument
;;
--default)
DEFAULT=YES
;;
*)
# unknown option
;;
esac
shift # past argument or value
done
echo FILE EXTENSION = "${EXTENSION}"
echo SEARCH PATH = "${SEARCHPATH}"
echo LIBRARY PATH = "${LIBPATH}"
echo "Number files in SEARCH PATH with EXTENSION:" $(ls -1 "${SEARCHPATH}"/*."${EXTENSION}" | wc -l)
if [[ -n $1 ]]; then
echo "Last line of file specified as non-opt/last argument:"
tail -1 $1
fi
#!/bin/bash
for i in "$@"
do
case $i in
-e=*|--extension=*)
EXTENSION="${i#*=}"
shift # past argument=value
;;
-s=*|--searchpath=*)
SEARCHPATH="${i#*=}"
shift # past argument=value
;;
-l=*|--lib=*)
LIBPATH="${i#*=}"
shift # past argument=value
;;
--default)
DEFAULT=YES
shift # past argument with no value
;;
*)
# unknown option
;;
esac
done
echo "FILE EXTENSION = ${EXTENSION}"
echo "SEARCH PATH = ${SEARCHPATH}"
echo "LIBRARY PATH = ${LIBPATH}"
echo "Number files in SEARCH PATH with EXTENSION:" $(ls -1 "${SEARCHPATH}"/*."${EXTENSION}" | wc -l)
if [[ -n $1 ]]; then
echo "Last line of file specified as non-opt/last argument:"
tail -1 $1
fi
#!/bin/sh
# POSIX
# Reset all variables that might be set
file=
verbose=0 # Variables to be evaluated as shell arithmetic should be initialized to a default or validated beforehand.
while :; do
case $1 in
-h|-\?|--help) # Call a "show_help" function to display a synopsis, then exit.
show_help
exit
;;
-f|--file) # Takes an option argument, ensuring it has been specified.
if [ -n "$2" ]; then
file=$2
shift
else
printf 'ERROR: "--file" requires a non-empty option argument.\n' >&2
exit 1
fi
;;
--file=?*)
file=${1#*=} # Delete everything up to "=" and assign the remainder.
;;
--file=) # Handle the case of an empty --file=
printf 'ERROR: "--file" requires a non-empty option argument.\n' >&2
exit 1
;;
-v|--verbose)
verbose=$((verbose + 1)) # Each -v argument adds 1 to verbosity.
;;
--) # End of all options.
shift
break
;;
-?*)
printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
;;
*) # Default case: If no more options then break out of the loop.
break
esac
shift
done
# if --file was provided, open it for writing, else duplicate stdout
if [ -n "$file" ]; then
exec 3> "$file"
else
exec 3>&1
fi
# Rest of the program here.
# If there are input files (for example) that follow the options, they
# will remain in the "$@" positional parameters.
#!/bin/bash
# Erratic behavior of the "$*" and "$@" internal Bash variables,
#+ depending on whether or not they are quoted.
# Demonstrates inconsistent handling of word splitting and linefeeds.
set -- "First one" "second" "third:one" "" "Fifth: :one"
# Setting the script arguments, $1, $2, $3, etc.
echo
echo 'IFS unchanged, using "$*"'
c=0
for i in "$*" # quoted
do echo "$((c+=1)): [$i]" # This line remains the same in every instance.
# Echo args.
done
echo ---
echo 'IFS unchanged, using $*'
c=0
for i in $* # unquoted
do echo "$((c+=1)): [$i]"
done
echo ---
echo 'IFS unchanged, using "$@"'
c=0
for i in "$@"
do echo "$((c+=1)): [$i]"
done
echo ---
echo 'IFS unchanged, using $@'
c=0
for i in $@
do echo "$((c+=1)): [$i]"
done
echo ---
IFS=:
echo 'IFS=":", using "$*"'
c=0
for i in "$*"
do echo "$((c+=1)): [$i]"
done
echo ---
echo 'IFS=":", using $*'
c=0
for i in $*
do echo "$((c+=1)): [$i]"
done
echo ---
var=$*
echo 'IFS=":", using "$var" (var=$*)'
c=0
for i in "$var"
do echo "$((c+=1)): [$i]"
done
echo ---
echo 'IFS=":", using $var (var=$*)'
c=0
for i in $var
do echo "$((c+=1)): [$i]"
done
echo ---
var="$*"
echo 'IFS=":", using $var (var="$*")'
c=0
for i in $var
do echo "$((c+=1)): [$i]"
done
echo ---
echo 'IFS=":", using "$var" (var="$*")'
c=0
for i in "$var"
do echo "$((c+=1)): [$i]"
done
echo ---
echo 'IFS=":", using "$@"'
c=0
for i in "$@"
do echo "$((c+=1)): [$i]"
done
echo ---
echo 'IFS=":", using $@'
c=0
for i in $@
do echo "$((c+=1)): [$i]"
done
echo ---
var=$@
echo 'IFS=":", using $var (var=$@)'
c=0
for i in $var
do echo "$((c+=1)): [$i]"
done
echo ---
echo 'IFS=":", using "$var" (var=$@)'
c=0
for i in "$var"
do echo "$((c+=1)): [$i]"
done
echo ---
var="$@"
echo 'IFS=":", using "$var" (var="$@")'
c=0
for i in "$var"
do echo "$((c+=1)): [$i]"
done
echo ---
echo 'IFS=":", using $var (var="$@")'
c=0
for i in $var
do echo "$((c+=1)): [$i]"
done
echo
# Try this script with ksh or zsh -y.
exit 0
# This example script written by Stephane Chazelas,
#+ and slightly modified by the document author.
#!/bin/bash
# arglist.sh
# Invoke this script with several arguments, such as "one two three" ...
E_BADARGS=85
if [ ! -n "$1" ]
then
echo "Usage: `basename $0` argument1 argument2 etc."
exit $E_BADARGS
fi
echo
index=1 # Initialize count.
echo "Listing args with \"\$*\":"
for arg in "$*" # Doesn't work properly if "$*" isn't quoted.
do
echo "Arg #$index = $arg"
let "index+=1"
done # $* sees all arguments as single word.
echo "Entire arg list seen as single word."
echo
index=1 # Reset count.
# What happens if you forget to do this?
echo "Listing args with \"\$@\":"
for arg in "$@"
do
echo "Arg #$index = $arg"
let "index+=1"
done # $@ sees arguments as separate words.
echo "Arg list seen as separate words."
echo
index=1 # Reset count.
echo "Listing args with \$* (unquoted):"
for arg in $*
do
echo "Arg #$index = $arg"
let "index+=1"
done # Unquoted $* sees arguments as separate words.
echo "Arg list seen as separate words."
exit 0
ROOT_UID=0 # Only users with $UID 0 have root privileges.
E_NOTROOT=87 # Non-root exit error.
# Run as root, of course.
if [ "$UID" -ne "$ROOT_UID" ]
then
echo "Must be root to run this script."
exit $E_NOTROOT
fi
SCRIPT_DIR=$(dirname $(readlink -f "${BASH_SOURCE[0]}"))
echo ${SCRIPT_DIR}
variable="line one\nline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment