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 functionalityexpr
command
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:
-c
text file exists-d
directory exists-e
file exists-f
file exists and is a regular file-h
file exists and is a symbolic link-r
file can be read-w
file can be written to-x
file can be runfile1 -nt file2
file1 is newer than file2file1 -ot file2
file1 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