Quick guide to shell scripts in BASH
BASH Quotes examples
BASH Get Options
POST to API with cURL
BASH references and shortcuts
BASH Snippets
Ascii Art
What is BASH?
BASH stands for the B
ourne A
gain SH
ell, which is based on the UNIX C
Shell and the Korn Shell. It is POSIX2 compliant.
The shell is the way users or scripts communivate with the Kernel. See https://askubuntu.com/questions/161511/are-the-linux-utilities-parts-of-the-kernel-shell for info on shells and kernels.
Bash Config files
Your home directory will containup to 3 files for configuring BASH, the default system wide file is /etc/profile
, but ~/.bash_profile will override this. It is read every time you log in.
~/.bashrc
is run each time you start a subshell.
~/.bash_logout
is run when a login shell exits.
~/.bash_history
is not really a config file, but stores a list of the commands you have run.
Developed over time, these are frameworks which allows me to concentrate on the purpose of the script, the “boilerplate” code is already written and handles the boring stuff such as parsing input, reporting errors and writing log files.
tab=$(echo -en “\t”)
bash-3.00$ tab=$(echo -en "\t") bash-3.00$ echo "test $tab test" test test bash-3.00$ echo "test${tab}test" test test bash-3.00$ echo "test${tab}${tab}test" test test bash-3.00$
value too great for base
probably refers to an arithmetic operation on a single 8 or 9 with a leading 0, ie. 08 or 09. Bash assumes this is an octal number from the leading 0 but 8 & 9 are not legal octal characters.
You can specify the base of a number using base#number
, usage is:-
RTTMP7=$((10#$RTTMP6 + 10#$RTTMP4))
Join two or more commands together, just rune them in turn and don't care if they succeed or fail:-
$ command1 ; command2
Logical AND, first command must succeed or second won't get run:-
$ mkdir newdir && cd newdir
Logical OR, runs second command when 1st fails:-
$ [-d newdir ] || mkdir newdir
Combining them:-
$ [-d newdir ] || mkdir newdir && cd newdir
Arithmetic Comparisons | |
---|---|
-lt | < |
-gt | > |
-le | ⇐ |
-ge | >= |
-eq | == |
-ne | != |
String Comparisons | |
---|---|
= | equal |
!= | not equal |
< | less then |
> | greater then |
-n s1 | string s1 is not empty |
-z s1 | string s1 is empty |
Unlike setting variables where a space round the VARIABLE=value
is required, comparison operators NEED a space round the operator, thinking on this, setting a variable and testing it are quite different operations, but the =
and ==
for variable setting and testing numeric equality do superficially look similar.
ACTION=${1} if [ "${ACTION}" = "start" ]; then echo "Starting Apache instances" elif [ "${ACTION}" = "stop" ]; then echo "Stopping Apache instances" else echo "No parameter passed, Useage:- startstopapache.sh start|stop" exit 2 fi
#!/bin/bash FABRIC=$1 if [ "${FABRIC}" = "" ] then echo "You need to provide a Fabric number, either 1 or 2" exit 1 fi
AND if [ "${FABRIC}" != "1" ] && [ "${FABRIC}" != "2" ] then echo "Fabric values can only be 1 or 2" fi
OR if [ ${CPRESULT} != 0 ] || [ ${CPUSERRESULT} != 0 ] then THRESHOLD=1 fi
if [ -z "${1}" ] || [ -z "${2}" ]; then printf "Usage:- assumerole.sh <account> <role to assume> \n" exit 1 fi
Specify a range of variables to work with
for i in {1..5}
for VARIABLE in bar boyl gm ppy or for VARIABLE in `cat FILENAME` do echo "WebSite is ${VARIABLE}, acton is ${ACTION}" done
break
causes the loop to quit, continue
just exits the current iteration of the loop, it will just carry on with the next loop iterator value.
# use for loop read all GC servers for (( gc=0; gc<${GCLENGTH}; gc++ )); do echo "Using >${GLOBALCATALOG[$gc]}<" echo "===============================" echo "" ldapsearch -x -L -h ${GLOBALCATALOG[$gc]} -D "${CN}" -W -b "${SEARCHBASE=}" -s sub proxyAddresses LDAPSEARCHRESULT=$? if [ ${LDAPSEARCHRESULT} = 0 ] then break fi done
while ($line = <SERIAL>) { print "$line\n"; }
DURATION=$(time (tar -xvzf ${TARLOCATION}/ww-wiki-backup-${DAY}.tar.gz > /dev/null 2>&1) 2>&1) TARRESULT=$? echo "untar result is >${TARRESULT}<, " >> ${TMPLOG} echo -n "Explode return code is >${TARRESULT}<, it took" >> ${TMPLOG} echo "${DURATION}" >> ${TMPLOG} echo "" >> ${TMPLOG}
Use #
for start of variable or %
for the end of the variable.
[ scripts]$ FILE=admin.log.bz2
[ scripts]$ echo $FILE admin.log.bz2 [ scripts]$ FILE=${FILE%.bz2} [ scripts]$ echo $FILE admin.log
Basic use:-
$ wget --user='user' --password='pw' 'http://www.yoursite.com/index.html'
wget with login page and cookie is a two stage process. First, login and retreive cookie, secondly use this cookie to download resource:-
$ wget --save-cookies tmpcookies.txt --post-data 'user=user&password=pw' http://www.yoursite.com/login.html $ wget --load-cookies tmpcookies.txt -p http://www.yoursite.com/protectedcontent.html
curl is somewhat similar:-
$ curl -u 'user:pw' 'http://www.yoursite.com'
#/bin/bash # written Andrew Stringer 26/07/2013 #Aimlessly spins round waiting for something function spinner() { local delay=0.75 local spinstr='/-\|' printf "...\n" while [ true ]; do local temp=${spinstr#?} printf "[%c]" "$spinstr" local spinstr=$temp${spinstr%"$temp"} sleep $delay printf "\b\b\b" done } echo "Waiting for 10s." echo "================" spinner & LAST_SPINNER_PID=$! sleep 10 kill ${LAST_SPINNER_PID} echo "" echo "Finished!" echo ""
$ ./spinner.sh Waiting for 10s. ================ ... [-] Finished!
#!/bin/bash DIR=H if [ -d $DIR ]; then echo "Dir $DIR exists" else mkdir H fi
rsync -av src dest
Bash array example, indices start at zero, so below [1] returns the second element ('example'):-
$ andrewsArray=(test example "three" 4) $ echo ${andrewsArray[1]} $ for i in ${andrewsArray[@]}; do ./pipeline --value $i done $ andrewsArray+=( "newItem1" "newItem2" )
$ echo 'username:new_password' | sudo chpasswd
Remove comments starting with #
from a file.
sed -e "/^#/d" <filename> > outputfile
-e
is the regex expression (tautology noted…), ^
anchors to the start of the line, d
deletes what is matched.
Remove last line of file
sed -i '$d' myfile.txt
-i
allows sed to edit the file in place.
I just want the files in a zip archive, without the Archive
header or testing
prefix added to each line.
Also, as I need to compare zip files from a bash zip command and from a python equivalent, I want to sort them so diff
can compare:-
$ unzip -t /tmp/boto3_python-1.26.59.zip | more Archive: /tmp/boto3_python-1.26.59.zip testing: __pycache__/ OK testing: bin/ OK testing: boto3/ OK testing: boto3-1.26.59.dist-info/ OK
$ unzip -t boto3_python-1.26.59.zip | sed 's/^ testing: //' | sed '/^Archive:/d' | sort > unzup-python-raw.txt
read -p "AWS region [default is:- eu-west-2]:-" AWS_REGION AWS_REGION=${AWS_REGION:-eu-west-2}
# remove any existing directories if they match the current release. if [ -d "$LIB_DIR" ]; then rm -rf ${LIB_DIR}; fi mkdir -p ${LIB_DIR}
This page has been accessed:-
Today: 1
Yesterday: 1
Until now: 337