Bash Scripting FAQ
Other resources:
- See also the official Bash FAQ.
- Bash's examples directory has lots of useful examples.
- Advanced Bash-Scripting Guide
- Bash Cookbook
- A good intro tutorial by Dan Robbins, Gentoo founder.
- Of course the official manual may come in handy too.
Contents
- 1 Loop over some command's output
- 2 How do I check to see if an external executable is available?
- 3 How do I get the short name of this script
- 4 How can I debug?
- 5 How do I get my quoting right? (file paths with spaces; security concerns)
- 6 Concatenate strings?
- 7 Substring function?
- 8 Get a file's basename, dirname, extension, etc?
- 9 Include another script (e.g. a script of functions)?
- 10 Check to see if script is running as root?
Loop over some command's output
Loop breaking on any whitespace
for word in `cat somefile` do echo Do something with $word here. done
Loop breaking on lines (useful if directories have spaces in them)
find . -iname "*.jpg" | while read file do echo Do something with $file here. done
How do I check to see if an external executable is available?
Replace jhead basename find mkdir mogrify cp
with the list of executables you want to check for. This snippet was taken from Thomas Hopfner's img2html script.
for tool in jhead basename find mkdir mogrify cp; do if ! type $tool >/dev/null 2>&1; then echo "ERROR: \"$tool\" not found." echo " This is needed by $scriptname to work. Check your" echo " \$PATH variable or install the tool \"$tool\"." exit 2 fi done
How do I get the short name of this script
scriptname=`basename "$0"`
Or better:
scriptname=
How can I debug?
To see the source as it executes through it, run your script like this:
bash -v script.sh
or add this to the beginning of your script:
set -v
To see the expressions evaluated as the script runs, execute your script like this:
bash -x script.sh
or add this to the beginning of your script:
set -x
How do I get my quoting right? (file paths with spaces; security concerns)
When executing anything, quote your variables if they are a single argument. Bash will quote the variable for you.
mkdir -p "$destdir"Don't quote if the argument variable might be empty, or if the variable is more than one parameter to the executable. In the following example, if
$recursive
is set, we get find . '' -iname "*.jpg" ...and if
$recursive
is not set, we get find . '-maxdepth 1' -iname "*.jpg" ...Neither of these is correct. In this case, we should not quote $recursive_param.
if [ "$recursive" ] then recursive_param="" else recursive_param="-maxdepth 1" fi # this is bad; $recursive_param should not be quoted find . "$recursive_param" -iname "*.jpg" -or -iname "*.gif" -or -iname "*.png" | while read file do # ... done
When doing tests (if and case statements), quote your variables:
if [ ! "$force" ] && [ -e "$destfile" ] then if [ "$verbose" ] then echo Skipping $destfile fi fi
Concatenate strings?
fullfilepath="$dirname$basename"
Or:
fullfilepath="doesnt_change/${dirname}also_doesnt_change/${basename}.log"
( assuming $dirname includes a trailing '/' )
Substring function?
Use ${var:offset:length}
myvar=abcdef slice_of_myvar=${myvar:3:2}
Get a file's basename, dirname, extension, etc?
See bash/examples/functions/basename and bash/examples/functions/basename2
# set the 'file' variable first # get extension; everything after last '.' ext=${file##*.} # basename basename=`basename "$file"` # everything after last '/' basename=${file##*/} # dirname dirname=`dirname "$file"` # everything before last '/' basename=${file%/*}
Include another script (e.g. a script of functions)?
Note: Test this; add full example
source util_functions.sh
Check to see if script is running as root?
if [ `id -u` != "0" ]; then echo "Sorry, you are not root." exit 1 fi