This is my simple Linux commands and bash reference.
Table of contents
- Running Scripts
- Redirecting Input and Output
- Miscellaneous
- Variables
- Working with Arrays
- Script Arguments
- Conditional Statements
- CASE Instruction
- Loops
- Commands:
- Examples
Running scripts
-x – run the script and show the commands being issued:
$ echo date > show_date.sh $ chmod u+x show_date.sh $ bash -x show_date.sh + date Sun May 8 15:08:20 EDT 2016
& – executing commands to run in background.
Redirecting Input/Output
>– redirect standard output>>– redirect standard output – append mode2>– redirect standard error output<- redirect standard input|- pipe one command's output as input to another command<<- used to provide input for a command - the following will produce file myfile.txt with three lines:$ cat > myfile.txt << END > a > b > c > END $ cat myfile.txt a b c
Miscellaneous
~ - shortcut to home directory:
$ pwd /home/oracle/Desktop/scripts $ cd ~ $ pwd /home/oracle
`...` (backquote) - used to replace a command with its output:
$ `echo pw``echo d` /home/oracle/Desktop/scripts
echo prints its arguments, which results in pwd. Since it is the first word, it is treated as a command to be executed.
$ touch a $ touch "a b.txt" $ find . -name "*.txt" ./a b.txt $ rm `find . -name "*.txt"` rm: cannot remove `b.txt': No such file or directory $ ls -1 a b.txt
One needs to be careful with names that have spaces: in the above example rm removed the a file instead of a b.txt.
Quotes and apostrophes - prevent interpreter from substituting characters like *
Apostrophes also make interpreter treat strings of $var type as a regular string, not a variable:
$ VAR=value $ echo $VAR value $ echo $VAR * value myfile.txt $ echo "$VAR *" value * $ echo '$VAR *' $VAR *
Calling subshell = using parentheses, a set of instruction can be run in a subshell, and their output can be treated as a whole for next command:
$ (for i in *.txt; do cat $i; done) | sort
Variables
Assigning a value:
variable_name=value
$ - use dollar sign to access the value:
echo $variable_name
# - use to get the length of a variable:
$ echo ${#variable_name}
5
Calculation of arithmetic expressions - two possibilities:
$[ ... ]- built-in bash functionalityexprcommand
Dollar signs are not required in front of variables inside $[ ... ] and * is not considered a pattern.
Examples:
$ var=$[2 + 2] $ echo $var 4 $ var=`expr $var \* 2` $ echo $var 8 $ var=`expr $var * 2` expr: syntax error $ var=`expr var \* 2` expr: non-numeric argument
expr requires dollar signs and escaping * with \
environment variable - to make a variable an environmental variable (and available to child processes), it must be exported:
$ export MYVAR=abc # or $ MYVAR=abc $ export MYVAR
Checking length of a variable: ${#variable}
Working with Arrays
Using arrays:
array=(Cake Cookie "Ice Cream")
array[3]=Fruit
echo $array # -> Cake - $array points to the first element
echo ${array[1]} # -> Cookie
echo ${array[*]} # -> Cake Cookie Ice Cream Fruit
echo ${array[@]} # -> Cake Cookie Ice Cream Fruit
echo ${!array[*]} # -> indexes: 0 1 2 3
echo ${#array[*]} # -> 4 - the number of elements
echo ${#array[3]} # -> 5 - the length of fourth element
# extract two elements, starting at index 1
echo ${array[@]:1:2} # -> Cookie Ice Cream
# extract part of a given element, starting at index 0
echo ${array[0]:0:3} # -> Cake
The difference between [*] and [@]:
array2=(${array[*]}) # returns elements split by spaces
array3=("${array[*]}") # returns a single element
array4=("${array[@]}") # returns elements as in the orignal array
echo \${array2[*]}
for i in ${!array2[*]}; do
echo ${array2[$i]}
done
echo \"\${array3[*]}\"
for i in ${!array3[*]}; do
echo ${array3[$i]}
done
echo \"\${array4[@]}\"
for i in ${!array4[*]}; do
echo ${array4[$i]}
done
Output:
${array2[*]}
Cake
Cookie
Ice
Cream
Fruit
"${array3[*]}"
Cake Cookie Ice Cream Fruit
"${array4[@]}"
Cake
Cookie
Ice Cream
Fruit
Script Arguments
Script arguments can be accessed using:
$1,$2, ...,$9- for the first nine arguments- (for example)
${13}- for other arguments
Other values:
$0- name of the script$#- number of arguments$@- all script's arguments$*- all script's arguments
Difference between the last two:
./foo.sh "a a" "b b" "c c"
asterisk "$*": "a a b b c c"
at-sign "$@": "a a" "b b" "c c"
Without the quotes, they're the same:
asterisk $*: "a" "a" "b" "b" "c" "c"
at-sign $@ "a" "a" "b" "b" "c" "c"
shift [n] command can be used to shift arguments to the right, losing the first argument $1, and moving argument $2 to its position, moving $3 to $2 and so on - n, by default 1, specifies number of arguments to be shifted. $# and $@ are updated after a shift.
Conditional Statements
Conditional statements - if..then..elif..else..fi - syntax:
if condition1; then ... elif conditon2; then ... else ... fi
test - command which evaluates its arguments - if they are true, it returns with code 0, and 1 otherwise.
$ if test 1 == 1; then echo 1 == 1; else echo 1 != 1; fi 1 == 1
Instead of using test, square brackets can be used:
$ if [ 1 == 1 ] ; then echo 1 == 1; else echo 1 != 1; fi 1 == 1
AND and OR - && and ||
test command flags - files:
-ctext file exists-ddirectory exists-efile exists-ffile exists and is a regular file-hfile exists and is a symbolic link-rfile can be read-wfile can be written to-xfile can be runfile1 -nt file2file1 is newer than file2file1 -ot file2file1 is older than file2
Arithmetic operations:
-eq- equal to-ne- not equal to-lt- lower than-le- lower equal-gt- greater than-ge- greater equal
String operations:
=- equal!=- not equal<- first string is "smaller">- first string is "larger"-n- expression has length > 0-z- expression has length = 0
CASE instruction
Syntax of case instruction:
case variable in pattern1) instruction1 ;; pattern2) instruction2 ;; * instruction_else ;; esac
* - can be used to match any (also empty) character string (for example c*t matches cat, caat, cut, and so on),
? - can be used to match a single character.
Example:
case $1 in pattern1) echo ;; pattern2) instruction2 ;; * instruction_else ;; esac
Loops
while .. do loop syntax:
while condition; do instruction; done
Example:
$ i=4 $ while [ $i -gt 0 ] ; do > echo $i; > i=$[i - 1]; >done 4 3 2 1
Or, in one line: while [ $i -gt 0 ] ; do echo $i; i=$[i - 1]; done
for loop:
for var in list; do instruction; done
Or, to iterate over program's arguments ($1, $2 and so on):
for var; do instruction; done
Commands
find
find - has an -exec option which can perform an action on every found file:
$ find . -name "*.txt" -exec rm "{}" \;
{} is replaced by the name of the found file
\; - one invocation per found file
+ - collects filenames up to ARG_MAX and then executes the command - less invocations than using \;
Example:
find . -name "*.txt" -exec rm "{}" +
There's also -execdir option - difference is that -exec executes the command from the starting directory, whereas the -execdir from the directory where the file has been found:
$ touch a.txt $ mkdir subdir $ touch subdir/b.txt $ find . -name "*.txt" -exec pwd \; /home/oracle/Desktop/scripts/rm_test /home/oracle/Desktop/scripts/rm_test $ find . -name "*.txt" -execdir pwd \; /home/oracle/Desktop/scripts/rm_test/subdir /home/oracle/Desktop/scripts/rm_test
cat
cat - prints its input:
cat > test.txt line1 line2 ^D cat test.txt line1 line2 <-- no new line here
ls and dir
ls and dir - dir's default output format does not depend on the type of the output device type - it's always vertically sorted columns, whereas in case of ls, it outputs one file per line if the output device is not the terminal.
ls -1 - one file per line (minus one, not minus lower-case L)
wc
wc -l - count lines
wc -c - count bytes - also counts newline
wc -m - count characters - also counts newline
echo and printf
echo outputs carrige return, printf does not:
$ echo t > wc_test $ printf t > wc_test2 $ wc -c wc_test 2 wc_test $ wc -c wc_test2 1 wc_test2 $ wc -m wc_test 2 wc_test $ wc -m wc_test2 1 wc_test2
read
read command - reads one line from standard input and splits it into words, putting the tokens into variables passed to read - the remaining words are stored in the last variable:
$ read x y one two three $ echo x = $x x = one $ echo y = $y y = two three
od
od command can be used to investigate the characters:
$ echo k | od -t c 0000000 k \n 0000002 $ od -t c wc_test 0000000 t \n 0000002 $ od -t c wc_test2 0000000 t 0000001
od - shows representation of characters:
-t a- named character display format-t c- ASCII character display format
$ od -t a wc_test 0000000 t nl 0000002
Examples
Removing a directory if it exists
- Check if a directory exists.
- Remove the directory and all its contents.
REPO_DIR=/my/dir if [ -d "$REPO_DIR" ]; then echo "Removing $REPO_DIR" rm -rf "$REPO_DIR" fi
