Notes on shell scripting in Linux. Should be used in conjunction with terminal notes: https://gist.github.com/IngmarBoddington/4226355
Basics
======
Expansion (special symbols replaced by values) and word splitting (arguments being split into several aruments) must have attemtion paid or pain will follow.
- # for comments
- Lots of internal variables available to bash scripts, see: http://tldp.org/LDP/abs/html/internalvariables.html#ARGLIST
- Name of script will be $0
- Parameters passed to script will be in $1, $2, $3.... vars and count in $#
- $? will return last exit message / return code for last command
- "$*" (with the quotes) returns all script arguments as single value separated by IFS
- $# number of arguments
- $@ full list of arguments as IX delimited value
- "$@" full list of args as seperate words
- $$ returns processId
- $- returns processId of last background process
- ${array[@]}: full array as IFS delimited value
- "${array[@]}": full array as seperate words
- No line terminators required but convention is semi-colon (EOL works fine)
- Use -e flag for echo's which include control characters (like \n)
- Using double quptes around variable identifiers evades word splitting arguments (single argument becoming many, often causes issues)
sh <script>
- Run script from terminal
- Don't need sh if file made executable to user
#!<commandIntepreter>
- Put at top of file to point command interpreter for rest of file (normally something like /bin/bash)
- #!/bin/sh will call the default shell interpreter
<identifier>=<value>;
- Local scalar assignment (avoid spaces around = operator)
<identifier>=(<spaceDelimitedValues>);
- List / Array assignment
- i.e. list=(item1 item2 ...) or list=([key1]=item1 [key2]=item2] ...)
$<identifier>
- Using assigned variables
exit [<string>]
- Exit with optional message
- If message is omitted the last command exit message will be returned / displayed
${<identifier>[<key>]}
- Get value of element of array
${<identifier>[@]}
- Return whole array (space delimited)
${#<identifier>[@]}
- Length of array
${#<identifier>}}
- Length of string
Capture output from command
- var=$(<command>);
- OLD: Use backticks for fetch results of bash commands, e.g. `ls` to return list of directory contents
- If failing to capture output from command, try appending 2>&1 to command (redirect stderr to stdout)
Prompting for input example (e.g.):
while true; do
read -p "Ignore (I) or Abort (A): " input
case $input in
[iI]* ) break;;
[aA]* ) exit;;
* ) echo "Please answer Ignore (I) or Abort (A): ";;
esac;
done;
IFS="<delimiter>"
- Use this to change the "Internal Field Separator" from the space default (auto list separator in loops etc)
IFS=$OIFS;
- Set IFS back to default
When entering a command the order of expansions is:
brace expansion, tilde expansion, parameter, variable and arithmetic expansion and command substitution (done in a left-to-right fashion), word splitting, and pathname expansion.
printf "format" <vars>
- Print formated string with vars interpolated (uses the standard %d, %s etc flags)
read lines from file example:
while IFS="" read -r LINE
do
echo $LINE
done < file
Control Structures
==================
If-else block:
if [ <condition> ]; then
<commands>
else
<commands>
fi;
For block
for <var> in <list>; do
<commands>;
done;
Case block
case <expression> in
<pattern1> )
<commands>;;
....
esac;
Function declaration
function <functionName> {
<commands>
}
While block
while <condition>; do
<commands
done;
Operators / Conditionals
========================
There is no concatenation operator, just put things side-by-side or use string interpolation
Comparison Operators (using 'test' / [)
Operators - format: [ <expr> <operator> <expr> ]
- Certain symbols (e.g. < redirect) should be avoided due to double meaning (use new test instead)
== is equal to (can use = instead)
!= is not equal to
-eq is equal to
-ne is not equal to
-gt is greater than
-ge is greater than or equal to
-lt is less than
-le is less than or equal to
[ $a == z* ] File globbing and word splitting take place.
[ "$a" == "z*" ] True if $a is equal to z* (literal matching).
Unary Operators - format: [ <operator> <expr> ]
-s (lowercase ‘s’) file is not zero size
-f file is a regular file (not a directory or device file)
-d file is a directory
-e file exists
-S file is a socket
-b file is a block device (floppy, cdrom, etc.)
-c file is a character device (keyboard, modem, sound card, etc.)
-p file is a pipe
-h file is a symbolic link
-L file is a symbolic link
-t file (descriptor) is associated with a terminal device
-r file has read permission (for the user running the test)
-w file has write permission (for the user running the test)
-x file has execute permission (for the user running the test)
-g set-group-id (sgid) flag set on file or directory
-u set-user-id (suid) flag set on file
-k sticky bit set
-O you are owner of file
-G group-id of file same as yours
-N file modified since it was last read
-n string is not “null.”
-z string is “null, ” that is, has zero length
f1 -nt f2 file f1 is newer than f2
f1 -ot f2 file f1 is older than f2
f1 -ef f2 files f1 and f2 are hard links to the same file
Also have 'new test' / [[ in most distros giving more options
no longer need to quote to evade word splitting of args
< is less than
<= is less than or equal to
> is greater than
>= is greater than or equal
=~ regular expression matching
[[ $<identifier = *<string>* ]] - True if string in variable
&& (and) and || (or) can be used to join [ ] / [[ ]] conditional blocks
Global Variables
================
BASH_VERSION: Contains a string describing the version of Bash.
HOSTNAME: Contains the hostname of your computer, I swear. Either short or long form, depending on how your computer is set up.
PPID: Contains the PID of the parent process of this shell.
PWD: Contains the current working directory.
RANDOM: Each time you expand this variable, a (pseudo)random number between 0 and 32767 is generated.
UID: The ID number of the current user. Not reliable for security/authentication purposes, alas.
COLUMNS: The number of characters that fit on one line in your terminal. (The width of your terminal in characters.)
LINES: The number of lines that fit in your terminal. (The height of your terminal in characters.)
HOME: The current user's home directory.
PATH: A colon-separated list of paths that will be searched to find a command, if it is not an alias, function, builtin command, or shell keyword, and no pathname is specified.
PS1: Contains a string that describes the format of your shell prompt.
TMPDIR: Contains the directory that is used to store temporary files (by the shell).