The command below executes specified subcommand command and loads its output into
positional variables ($1, $2, ...). Every output's part is separated by a sign from $IFS
variable:
set -- $( command )
for example:
set -- $( ls -l "file_name" )
returns: $1=-rwxr-xr-x, $2=1, $3=mzaleczny, $4=mzleczny, and so on.
Positional parameters can be deleted with command:
set --
Saves specified function in the environment so the function is available for all child processes:
export -f function_name
Displays all environment variables. In opposite to set command it doesn't display
exported functions:
printenv
Shifts all positional parameteres one step to the left. Parameter $1 gets removed, parameter $2 becomes parameter $1,
parameter $3 becomes parameter $2, and so on:
shift
Shifts all positional parameteres specified amount of steps to the left. First number of parameters
get removed:
shift number
Exits current script with return code equal to number:
exit number
Tests if current working directory contains file or directory "name":
test -a name
Tests if current working directory contains special block file "file_name":
test -b file_name
Tests if current working directory contains special character file "file_name":
test -c file_name
Tests if current working directory contains directory "directory_name":
test -d directory_name
Tests if current working directory contains file or directory "name":
test -e name
Tests if current working directory contains regular file "file_name":
test -f file_name
Tests if current working directory contains file "file_name" and if it has set-group-id bit set:
test -g file_name
Tests if current working directory contains symbolic link "name":
test -h name
or
test -L name
Tests if current working directory contains file "file_name" and if it has sticky-bit set:
test -k file_name
Tests if current working directory contains named stream (FIFO) "name":
test -p name
Tests if current working directory contains file or directory "name" and if it is readable:
test -r name
Tests if current working directory contains file "file_name" and if its size is greater than 0:
test -s file_name
Tests if specified descriptor "descriptor_number" is opened and attached to a terminal (keyboard or screen):
test -t descriptor_number
Tests if current working directory contains file "file_name" and if it has set-user-id bit set:
test -u file_name
Tests if current working directory contains file or directory "name" and if it is writable:
test -w name
Tests if current working directory contains file or directory "name" and if it is executable:
test -x name
Tests if current working directory contains file or directory "name" and if its owner is effective group id:
test -G name
Tests if current working directory contains file "file_name" and if it has changed since it's last read:
test -N file_name
Tests if current working directory contains file or directory "name" and if its owner is effective user id:
test -O name
Tests if two specified files are located in the same file system and if they are associated to the same i-node:
test file_name1 -ef file_name2
Tests if file_name1 is newer (according to modification date) than file_name2 or if file_name1 exists and file_name2 does not:
test file_name1 -nt file_name2
Tests if file_name1 is older (according to modification date) than file_name2 or if file_name2 exists and file_name1 does not:
test file_name1 -ot file_name2
Tests if specified variable is set:
test -v variable_name
Tests if specified string is empty (its length is 0):
test -z string
Tests if specified string is not empty (its length is greater than 0):
test -n string
Returns true if content of both specified variables is the same, returns false otherwise:
test "$variable1" == "$variable2"
or
test "$variable1" = "$variable2"
Returns true if content of both specified variables is different, returns false otherwise:
test "$variable1" != "$variable2"
Returns true if string $variable1 sorts before $variable2, returns false othewrwise:
test "$variable1" < "$variable2"
Returns true if string $variable1 sorts after $variable2, returns false othewrwise:
test "$variable1" > "$variable2"
Returns true if both specified integer variables are equal:
test $variable1 -eq $variable2
Returns true if both specified integer variables are not equal:
test $variable1 -ne $variable2
Returns true if integer variable $variable1 is less than integer variable $variable2:
test $variable1 -lt $variable2
Returns true if integer variable $variable1 is less than or equal to integer variable $variable2:
test $variable1 -le $variable2
Returns true if integer variable $variable1 is greater than integer variable $variable2:
test $variable1 -gt $variable2
Returns true if integer variable $variable1 is greater than or equal to integer variable $variable2:
test $variable1 -ge $variable2
Synonym of the test command are two square brackets separated with white character to the left and
to the right. Just after the closing bracket can be also put a semicolon, for example:
if test -f file_name; then
is synonym to:
if [ -f file_name ]; then
Negated condition below returns true if file "file_name" does not exists:
if [ ! -f file_name ]; then
If conditional expression:
if condition; then
instructions_1
else
instructions_2
fi
If expanded conditional expression:
if condition; then
instructions_1
elif condition_2; then
instructions_2
elif condition_3; then
instructions_3
...
else
instructions_n
fi
for..in loop:
for variable in list-of-items-separated-with-character-from-$IFS; do
instructions
done;
Instruction below generates a numerical list starting at FROM to TO with incremental step STEP:
{FROM..TO..STEP}
for example:
{1..4..1} => 1 2 3 4
and:
{1..4..2} => 1 3
Command seq below also generates a numerical list starting at FROM to TO with incremental step STEP.
Generated items are separated by a new line character:
seq FROM STEP TO
for example:
seq 1 1 4 => 1\n2\n3\n4\n
and:
seq 1 2 4 => 1\n3\n
for loop:
for (( counter=1; counter<=10; counter+=2 )); do
instructions
done;
Loop through the positional variables $1, $2, ...
for variable; do
instructions
done;
while loop:
while condition; do
instructions
done;
The loop above processes the instructions as long as the condition evaluates to true.
The example of while loop as a destination of a stream:
cat file_name |
while read line; do
echo $line
done;
Example of while loop that write out the file line by line:
while read line; do
echo $line
done <text_file
until loop:
until condition; do
instructions
done;
The loop above processes the instructions as long as the condition evaluates to false.
In for, while and until loops one can use commands: continue and break.
case structure:
case value in
pattern_1)
instructions_1
;;
pattern_2)
instructions_2
;;
...
*)
default_instructions
;;
esac
Select command displays menu that contains items specified after in keyword and assigns selected item to a variable variable placed just after select keyword. Next it runs commands placed between do and done keywords until it encounter break statement. The selected number is stored in $REPLY variable. The prompt is set in the $PS3 variable (by default it is #? string):
select variable in item_1 item_2 ...
do
instructions
...
break
done
Example:
#!/bin/bash
clear
select variable in cap scarf gloves
do
if [ "$variable" == "" ]; then
echo Nothing is chosen
continue
fi
echo $REPLY --- $variable
break
done
Redirecting script fragment to the standard input of a command:
#!/bin/bash
wc -l <<_END_
line_1
line_2
line_3
_END_
The script above displays count of lines redirected to the standard input of the wc command.
$RANDOM variable generates an integer number from <1..32766> range.
Incrementing integer number variable by 1:
(( i += 1 ))
Function definition:
function f_name()
{
instructions
}
Removes function f_name:
unset f_name
break instruction causes immidiately function exit.
Local variables of functions are defined with use of local keyword, for example:
local name="Marcin";
If a variable is defined without of local keyword then the variable is global one
available from outside of the function, ex.:
name="Marcin";
Saves specified function in the environment so the function is available for all child processes:
export -f f_name
Variables passed to function are available in the positional parameters: $1, $2, $3, ... The count of passed function arguments is available in $# variable.
Function:
function my_function()
{
echo "Parameters count:" $# "-" $1 $2 $3
}
can be called in following way (with parameters passed):
my_function 1 "param 2" 3
Opens descriptor 3 (standard input duplicate) and 4 (standard output duplicate):
exec 3<&0 4>&1
Opens descriptor 3 (file specified in $1 variable as an input) and 4 (duplikat standardowego wyjścia):
exec 3< $1 4>&1
Opens descriptor 3 (file specified in $1 variable as an input) and 4 (file specified in $2 variable as an output):
exec 3< $1 4> $2
Closes descriptors 3 and 4:
exec 3<&- 4<&-
Reads data from descriptor 3 and writes it to descriptor 4:
cat <&3 >&4
Declares simple array:
FRUITS=(apple pear cherry strawberry)
Numeration of an array elements starts with 0. Below there is an access to the second array element:
${FRUITS[1]} - pear
Making an array duplication:
DUPLICATE=("${FRUITS[@]}")
Creating a new array that have one element consisting of all elements of the FRUITS array separated by the first
character of $IFS variable (usually space):
NEW_ARRAY=("${FRUITS[*]}")
Example of declare -a (creating array-type variables):
declare -a DUPLICATE='([0]="apple" [1]="pear" [2]="cherry" [3]="strawberry")'
declare -a NEW_ARRAY='([0]="apple pear cherry strawberry")'
Displays count of array elements:
echo ${#FRUITS[*]}
Displays size of a specified array element:
echo ${#FRUITS[1]}
Displays array's content:
echo ${OWOCE[*]}
Reads from standard input a line and assigns it to the line variable:
read -p "Type in a line: " line
Reads from standard input two words and assigns it to the word1 and word2 variables
(if there are more than two words then word2 holds all words starting from the second one):
read -p "Type in two words: " word1 word2
Reads a line from specified file descriptor (here 3) and assigns data to word1 and word2
variables (according to the rule described above). If the file was already opened and one read from it, then reading
from it will be continued from the current file position:
read -u3 word1 word2
Catching INT (2) signal and executing commands specified in apostrophes (here displaying a message and exiting the script
with error code 1):
trap 'echo Script catched INT signal. Exiting the script; exit 1' INT
Executes cleaning operations after script finished its task (either after explicit call to exit command or after all commands
were executed):
trap 'cleanup_before_exit' EXIT
getopts command processes all options passed from the command line to a script:
getopts [:]options current_option
for instance.:
getopts :u:h:d opt
Options argument consists of letters that can be passed to the script. If it starts from the colon
then the error (passing unrecognized option or ommitting argument for an option) handling will be ceded to the script.
If after a letter appears a colon (:), then the option takes an argument.
Parameter current_option (opt in the example above) in each call to getopts command contain
successive option letter. Additionally in each run there are set OPTIND (option number starting from 1)
and optionally OPTARG (argument for the current option, if it takes one) variables.
In the example below there is presented a way of processing options in script:
USER=
HOME_DIR=
DATE=0
while getopts :u:h:d opt; do
case $opt in
u) if [ -z "$OPTARG" ]; then
echo "Username not specified" >&2
exit 1
else
USER="$OPTARG"
fi
;;
h) if [ -d "$OPTARG" ]; then
HOME_DIR="$OPTARG"
else
echo "Specified directory does not exists" >&2
exit 1
fi
;;
d) DATE=1 ;;
:) echo "Option $OPTARG require an argument" >&2
exit 1
;;
\?) echo "Unrecognized option $OPTARG" >&2
exit 1
;;
esac
done
echo "Username $USER"
echo "Home directory: $HOME_DIR"
if [ $DATE -eq 1 ]; then
echo -n "DATE: "
date
fi
If the option argument (:) was not specified or unrecognized option (\?) was passed, then the $OPTARG variable holds the option name.
Calculating arithmetic expressions:
let "OUTCOME=VARIABLE_1 + VARIABLE_2 * 2"
or equivalent:
((OUTCOME=VARIABLE_1 + VARIABLE_2 * 2))
In the let command or in its bracket equivalent, variable names do not have to starts with $ prefix.
For calculating boolean expressions the following syntax is used:
[[ expression ]]
Within the expression all variables have to be prefixed with $, ex.:
if [[ 1 < $number && $number < 10 ]]; then
echo Number in range [2,9]
fi
Spaces around the square brackets [[ and ]] are required.
Checking if specified text matches the pattern (all spaces in the expression below are required):
[[ "TEXT_OR_VARIABLE" = M* ]]
ex.:
NAME=Marcin
returns true, while
[[ "$NAME" = M* ]][[ "$NAME" = m* ]] or [[ "$NAME" = a* ]]
return false.
Examples of removing prefix and postfix matches from a variable:
# - removes minimal matched prefix ## - removes maximal matched prefix % - removes minimal matched postfix %% - removes maximal matched postfixExamples:
EMAIL=mzaleczny@any.domain.pl
echo ${EMAIL#m*@} => any.domain.pl
echo ${EMAIL#m*.} => domain.pl
echo ${EMAIL##m*.} => pl
echo ${EMAIL%.*} => mzaleczny@any.domain
echo ${EMAIL%%.*} => mzaleczny@any
Returns length of string variable:
echo ${#EMAIL} => 23
Turns off displaying of typed in from the keyboard characters:
stty -echo
Turns on displaying of typed in from the keyboard characters:
stty echo