====== Bash ====== [[bash-quickguide|Quick guide to shell scripts in BASH]] \\ [[bash-quotes|BASH Quotes examples]] \\ [[bash-getoptions|BASH Get Options]] \\ [[bash-post-to-api|POST to API with cURL]] \\ [[bashshortcut|BASH references and shortcuts]] \\ [[bash-snippets|BASH Snippets]] \\ [[bash_aaart|Ascii Art]] \\ [[misc-bash-cgi|BASH cgi Misc info]] \\ **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. [[linux:bash-quickguide|Quick guide to shell scripts in BASH]] ===== Generic script frameworks ===== 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. [[linux:bash-generic-script-framework1|Generic script framework for non-interactive scripts]] [[rb:bash-generic-script-framework2|Generic script framework for interactive scripts]] ===== Misc ===== [[linux:bashshortcut|Bash reference and shortcuts sheet]] ==== Print tab character. ==== 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$ ==== Specifying the base of a number ==== ''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)) ==== Running multiple commands ==== 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 ===== Comparisons ===== ^ 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. ===== if elif else ===== 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 ===== if with multiple conditions ===== #!/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 \n" exit 1 fi ===== for loop ===== 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 ==== Exit from loop early ==== ''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 loop ===== while ($line = ) { print "$line\n"; } ===== Time duration of operation and record exit status ===== 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} ===== Remove first or last character from variable ===== 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 ===== Getting web page with wget ===== 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' ===== Spinner.sh ===== #/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! ===== Does directory exist ===== #!/bin/bash DIR=H if [ -d $DIR ]; then echo "Dir $DIR exists" else mkdir H fi ===== Copy all files between directories ===== rsync -av src dest ===== Arrays ===== 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" ) ===== Change user password from shell script ===== $ echo 'username:new_password' | sudo chpasswd ===== sed - stream editor ===== Remove comments starting with ''#'' from a file. sed -e "/^#/d" > 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. ==== Testing content of zip file ==== 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 ===== Default value for variable ===== read -p "AWS region [default is:- eu-west-2]:-" AWS_REGION AWS_REGION=${AWS_REGION:-eu-west-2} ===== Remove and recreate directory ===== # 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: {{counter|today}} \\ Yesterday: {{counter|yesterday}} \\ Until now: {{counter|total}} \\