$ which bash
---------------
2. Logical Operator
---------------
&&
if
[ $condition1 ] && [ $condition2 ]
||
if
[ $condition1 ] || [ $condition2 ]
Logical NOT:
! expression
or
[ ! expression ]
or
if test ! condition
then
command1
command2
fi
or
if [ ! condition ]
then
command1
command2
fi
---------------
3. Variable
---------------
Bash Variables Are Untyped.
Unlike many other programming languages, Bash does not segregate
its variables by
"type." Essentially,
Bash
variables are character strings, but, depending on
context,
Bash permits arithmetic operations and comparisons on
variables. The determining factor is whether the value of a
variable contains only digits.
STRING="Hello World"
VAR="global variable"
function bash {
local VAR="local variable"
echo $VAR
}
Default value:
#A="defined"
# "not defined" is the default value if A is not defined.
B=${A:=not defined} # also assign to A in addition assigned to B.
B=${A:-not defined} #
B=${1:-not defined} # if $1 not provided, then use "not defined"
Or
# shorten format of above. Note: :- is not working in shorten format.
: ${A:=not defined} # first : means do nothing.
echo $A
---------------
4. Passing arguments to bash scritp
---------------
# use predefined variables to access passed arguments
#echo arguments to the shell
echo $1 $2 $3 ' -> echo $1 $2 $3'
# We can also store arguments from bash command line in special array
args=("$@")
echo ${args[0]} ${args[1]} ${args[2]} ' -> args=("$@"); echo ${args[0]} ${args[1]} ${args[2]}'
#use $@ to print out all arguments at once
echo $@ ' -> echo $@'
# use $# variable to print out nummber of arguments passed to the bash script
echo $#
# command name : $0
# all parameters: $@ OR $*
# individual parameters: $1, $2, $3, etc...
# number of parameters: $#
# process number: $$
#
---------------
5. Execute shell command within bash
---------------
# use backticks " ` ` " to execute shell command
echo `uname -o`
--------------------------
6. Reading User Input
--------------------------
read word
read word1 word2
echo "Here is your input: \"$word1\" \"$word2\""
read ## into $REPLY
echo "You said $REPLY, I'm glad to hear that! "
read -a colours # into an array
echo "${colours[0]}, ${colours[1]} and ${colours[2]}"
--------------------------
7. Bash Trap Command : what to do when ctrl-c
--------------------------
#!/bin/bash
trap bashtrap INT
clear;
bashtrap()
{
echo "CTRL+C Detected !...executing bash trap !"
}
# for loop from 1/10 to 10/10
for a in `seq 1 10`; do
echo "$a/10 to Exit."
sleep 1;
done
echo "Exit Bash Trap Example!!!"
--------------------------
8. Arrays
--------------------------
# Element are separated by white space
# This array has four elements.
ARRAY=( 'Debian Linux' 'Redhat Linux' Ubuntu Linux )
echo ${ARRAY[0]} # print out one single element (0-based)
echo ${ARRAY[@]} # print out the entire elements
ELEMENTS=${#ARRAY[@]} # get number of elements in the array
for (( i=0;i<$ELEMENTS;i++)); do
echo ${ARRAY[${i}]}
done
declare -a ARRAY
let count=0
# read from file
while read LINE
do
ARRAY[$count]=$LINE
((count++))
done < $1 # $1 is the 1st param
# done < file_abc # Or hard-code file name.
echo ${#ARRAY[@]}
echo ${ARRAY[@]}
----------------------------------
9. Bash if / else / fi statements
----------------------------------
if [ -d $directory ]
then
echo "Directory exists"
else
echo "Directory does not exists"
fi
read choice
if [ $choice -eq 1 ]
then
echo "You have chosen word: Bash"
else
if [ $choice -eq 2 ] ; then
echo "You have chosen word: Scripting"
else
if [ $choice -eq 3 ] ; then
echo "You have chosen word: Tutorial"
else
echo -n "Please choose a word [1,2 or 3]? "
fi
fi
fi
--------------------------
10. Bash Comparisons
--------------------------
10.1. Arithmetic Comparisons
--------------------
use meaning
--------------------
-lt <
-gt >
-le <=
-ge >=
-eq ==
-ne !=
if [ $NUM1 -eq $NUM2 ]; then
echo "Both Values are equal"
else
echo "Values are NOT equal"
fi
10.2. String Comparisons
------------------------
use meaning
------------------------
= OR == equal
!= not equal
< less then
> greater then
-n s1 string s1 is not empty
-z s1 string s1 is empty
if [ $S1 = $S2 ]
then
echo "Both Strings are equal"
else
echo "Strings are NOT equal"
fi
--------------------------
11. Bash File Testing
--------------------------
-b filename Block special file
-c filename Special character file
-d directoryname Check for directory existence
-e filename Check for file existence
-f filename Check for regular file existence not a directory
-G filename Check if file exists and is owned by effective group ID.
-g filename true if file exists and is set-group-id.
-k filename Sticky bit
-L filename Symbolic link
-O filename True if file exists and is owned by the effective user id.
-r filename Check if file is a readable
-S filename Check if file is socket
-s filename Check if file is nonzero size
-u filename Check if file set-ser-id bit is set
-w filename Check if file is writable
-x filename Check if file is executable
if [ -e $file ]; then
echo "File exists"
else
echo "File does not exists"
fi
# Inverse of logical operator.
if [ ! -d $dir ]; then
echo "dir not exist."
else
echo "dir exits."
fi
--------------------------
12. Loops
--------------------------
for f in $( ls /var/ ); do
echo $f
done
$ for f in $( ls /var/ ); do echo $f; done
while [ $COUNT -gt 0 ]; do # true then execute
echo Value of count is: $COUNT
let COUNT=COUNT-1
done
COUNT=0
until [ $COUNT -gt 5 ]; do # false then execute
echo Value of count is: $COUNT
let COUNT=COUNT+1
done
find $DIR -type f | while read file; do
# using POSIX class [:space:] to find space in the filename
if [[ "$file" = *[[:space:]]* ]]; then
# substitute space with "_" character and consequently rename the file
mv "$file" `echo $file | tr ' ' '_'`
fi;
done
-------------------------
13. Bash Functions
-------------------------
Definition:
function function_B { echo Function B. }
function function_A { echo $1 }
function function_D { echo Function D. }
function function_C { echo $1 }
Usage:
function_A "Function A."
function_B
function_C "Function C."
function_D
# function take in parameters and return value.
function f
{
local val="$1 $2" # get input parameters
echo $val
}
a=3
b=4
c=$(f $a $b) # get return value
echo "c=$c"
---------------------
14. Bash Select
---------------------
# It creates a menu, from which option number such as 1 or 2 is chosen.
select word in "linux" "bash" "scripting" "tutorial"
do
echo "The word you have selected is: $word"
break
done
---------------------
15. Case statement conditional
---------------------
# Options could be anything, basically it tries to match
# $case with the value of one of the options.
read case;
case $case in
1) echo "You selected bash";;
2) echo "You selected perl";;
a) echo "You selected phyton";;
"a b") echo "You selected c++";;
5) exit
esac
Note: double semi-colon ";;" is similar to "break" statement in other
language such as Java.
---------------------
16. Bash quotes and quotations
---------------------
Single quotes in bash will suppress special meaning of every meta characters.
Double quotes in bash will suppress special meaning of every meta characters except "$", "\" and "`".
BASH_VAR="Bash Script"
echo $BASH_VAR
#when meta character such us "$" is escaped with "\" it will be read literally
echo \$BASH_VAR
# backslash has also special meaning and it can be suppressed with yet another "\"
echo "\\"
---------------------
17. Arithmetic Operations: no space allowed among = and operators.
---------------------
let RESULT1=$1+$2 ## way1 t o do arithmetic operations
echo $1+$2=$RESULT1
declare -i RESULT2
RESULT2=$1+$2
echo $1+$2=$RESULT2
echo $1+$2=$(($1 + $2)) ## way2 to do arithmetic operations
echo $1+$2=$[ $1 + $2 ] ## way3 to do arithmetic operations
let ADDITION=3+5
let SUBTRACTION=7-8
let MULTIPLICATION=5*8
let DIVISION=4/2
let MODULUS=9%4
let POWEROFTWO=2**2
# bash convert binary number 10001
result=2#10001 ## 2# means binary
result=8#16 ## 8# means octal
result=16#E6A ## 16# means hexdecimal
echo $result
17.3. Round floating point number
floating_point_number=3.3446
for bash_rounded_number in $(printf %.0f $floating_point_number); do
done
read userinput
echo "scale=2; ${userinput}" | bc
echo "scale=10; ${userinput}" | bc
echo $userinput | bc
-----------------
18. Redirections
-----------------
echo "Redirect this STDOUT to STDERR" 1>&2
cat $1 2>&1
$ ls file1 > STDOUT
$ ls file1 file2 2> STDERR
$ ls file1 file2 2> STDERR_STDOUT 1>&2
$ ls file1 file2 > STDERR_STDOUT 2>&1
----------------------
19. declare
----------------------
The declare or typeset builtins, which are exact synonyms, permit modifying the
properties of variables. This is a very weak form of the typing [1] available in certain programming languages.
The declare command is specific to version 2 or later of Bash.
The typeset command also works in ksh scripts.
declare/typeset options
-r readonly
(declare -r var1 works the same as readonly var1)
This is the rough equivalent of the C const type qualifier.
declare -r var1=1
echo "var1 = $var1" # var1 = 1
-i integer
declare -i number
Certain arithmetic operations are permitted for declared integer variables without the need for expr or let.
declare -i n
n=6/3
echo "n = $n" # n = 2
-a array
declare -a indices
-f function(s)
A declare -f line with no arguments in a script causes a listing of all the
functions previously defined in that script.
declare -f # do this from command line,you will see lots of function definitions, which will
basic syntax of bash. And this is the sole purpose of this blog.
declare -f f2 # Only list content of function f2.
-x export
This declares a variable as available for exporting outside the environment of the script itself.
declare -x var3
-x var=$value
The declare command permits assigning a value to a variable in the same statement as setting its properties.
declare -x var3=373
declare -r var2=13.36 # 'declare' permits setting a variable property
#+ and simultaneously assigning it a value.
9.2.1. Another use for declare
The declare command can be helpful in identifying variables, environmental or otherwise.
This can be especially useful with arrays.
bash$ declare | grep HOME
HOME=/home/bozo
bash$ zzy=68
bash$ declare | grep zzy
zzy=68
bash$ Colors=([0]="purple" [1]="reddish-orange" [2]="light green")
bash$ echo ${Colors[@]}
purple reddish-orange light green
bash$ declare | grep Colors
Colors=([0]="purple" [1]="reddish-orange" [2]="light green")
---------------------
20 ; means newline
---------------------
if you want to combines statements into one line, then you need semi-colon alot.
Key is to append ";" to the end of each statement.
Way1: without ;
a=3
b=` if [ $a -gt 4 ]
then
echo "bigger "
echo "jjj"
else
echo "smal"
echo "fsf"
fi `
echo $b
Way2 : with ;
a=3;b=` if [ $a -gt 4 ]; then echo "bigger " ; echo "111" ; else echo "small" ; echo "222"; fi `; echo $b
---------------------
21 eval
--------------------
Evaluate several commands/arguments
Syntax
eval [
arguments]
The arguments are concatenated together into a single command,
which is then read and executed, and its exit status returned as the exit status
of eval
. If there are no arguments or only empty arguments, the
return status is zero.
eg:
$ eval echo "abc" a=3 echo $a
abc a=3 echo 3
$ eval echo "abc" ; a=3 ; echo $a
abc
3
---------------------
22 set -ax
--------------------
-a Automatically mark variables and functions which are modified or
created for export to the environment of subsequent commands.
-x After expanding each simple command, for command, case command,
select command, or arithmetic for command, display the
expanded value of PS4, followed by the command and its
expanded arguments or associated word list.
dxu:
option "-x" is to expand arguments in commands, so it can be very helpful in debugging script.
option "-a" is really powerful, it sends all the variables to sub-scripts as ENV variables.
eg:
abc.sh
#!/bin/bash
set -a
## export TT="ddddd" ## <== I did NOT export TT.
TT="ddddd" ## "-a" in set will export TT automatically.
./def.sh
def.sh
#!/bin/bash
echo $TT
$ ./abc.sh
ddddd
---------------------
23 uid and gid
--------------------
$ groups # list all the groups you are in.
$ id # list uid (name and user#) and groups(name and group#)
Long list format of ls -l :
-rwxrw-r-- 10 root root 2048 Jan 13 07:11 afile.exe
- file permissions,
- number of links,
- owner name,
- owner group,
- file size,
- time of last modification, and
- file/directory name
---------------------
24 I/O
--------------------
declare -a ARRAY
let count=0
# 1 Read from file
while read LINE
do
ARRAY[$count]=$LINE
((count++))
echo "line is : $LINE"
done <
file_abc #
echo ${#ARRAY[@]}
echo ${ARRAY[@]}
# 2 write to file
echo "abc " > file_def
---------------------
25 trap
--------------------
# 1. List all the signals system support
[dxu@nco-lw-dxu bash]$
kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
# 2. trap error
testTrap.sh
#!/bin/bash
function error_msg {
echo "Overwrite default action for that singal "
echo "do whatever you want"
echo "process id = $$ "
}
# From here on, "trap" command will trap signal 2 if signal 2 is received
# Once receive the signal 2, do the following actions defined by cmd/function.
#1) use command explictly.
# trap 'echo "process id = $$" ; exit' 2 # only trap signal 2
# trap 'echo "process id = $$" ; exit' 1 2 3 # trap signals 1 2 and 3
#2) call a function
trap 'error_msg ; exit' 2
while [ 1 ]
do
echo "-----"
done
# use ctrl-C to generate signal 2.
$ ./testTrap.sh
Output:
-----
-----
^C-----
Overwrite default action for that singal
do whatever you want
process id = 31544
---------------------
26 scp
--------------------
Copy the file "foobar.txt" from a remote host to
the local host
$ scp your_username@remotehost.edu:foobar.txt /some/local/directory
Copy the file "foobar.txt" from the local host to
a remote host
$ scp foobar.txt
your_username@remotehost.edu:/some/remote/directory
Copy the directory "foo" from the local host to a
remote host's directory "bar"
$ scp -r foo your_username@remotehost.edu:/some/remote/directory/bar
Copy the file "foobar.txt" from remote host
"rh1.edu" to remote host "rh2.edu"
$ scp
your_username@rh1.edu:/some/remote/directory/foobar.txt \
your_username@rh2.edu:/some/remote/directory/
Copying the files "foo.txt" and
"bar.txt" from the local host to your home directory on the remote
host
$ scp foo.txt
bar.txt your_username@remotehost.edu:~
Copy the file "foobar.txt" from the local host to
a remote host using port 2264
$ scp -P 2264
foobar.txt your_username@remotehost.edu:/some/remote/directory
Copy multiple files from the remote host to your current
directory on the local host
$ scp your_username@remotehost.edu:/some/remote/directory/\{a,b,c\}
.
$ scp your_username@remotehost.edu:~/\{foo.txt,bar.txt\}
.
scp
Performance
By default scp uses the Triple-DES cipher to encrypt the
data being sent. Using the Blowfish cipher has been shown to increase speed.
This can be done by using option -c blowfish in the command line.
It is often suggested that the -C option for compression
should also be used to increase speed. The effect of compression, however, will
only significantly increase speed if your connection is very slow. Otherwise it
may just be adding extra burden to the CPU. An example of using blowfish and
compression:
$ scp -c blowfish -C local_file your_username@remotehost.edu:~
To get summary of new/missing files, and which files differ:
$ diff -arq folder1 folder2 # best command I've ever known.
-a --text
Treat all files as text.
-q --brief
Output only whether files differ.
-r --recursive
Recursively compare any subdirectories found.
How to use EOF in bash script
eg:
$ vi abc.sh
--------------------------------------------------------
#!/bin/bash
files=`ls *nts`
for file in $files
do
gdplot2_gif
<< EOF
rest $file
l
# Note: EOF must be aligned with first column,
# NO space is allowed in front of EOF
EOF
done
--------------------------------------------------------
How to use basename ( strip dir and suffix )
[dxu@nco-lw-dxu gfs_0p25]$ basename
/d1/d2/d3/abc.sh
abc.sh
[dxu@nco-lw-dxu gfs_0p25]$ basename abc.sh
.sh
abc
[dxu@nco-lw-dxu gfs_0p25]$ basename abc_def_
_def_
abc
Change cases to lower/upper case
Eg:
a="HEllo Everyone!"
# Various ways to do convert cases.
tr $ echo $a | tr '[:upper:]' '[:lower:]'
awk $ echo $a | awk '{print tolower($0)}'
Perl $ echo $a | perl -ne 'print lc'
Remove blank lines
$ sed -e "/
^$/d" abc # find blank line ^$ and then delete
$ sed -e "/
^ *$/d" abc # find line made of spaces and then delete
Find command
1) By hour:
atime :
access time
ctime :
changed time
mtime :
modified time
eg:
-mtime +3 # 3
hours ago
-mtime 3 #
Exactly 3 hours ago
-mtime -3 #
within 3 hours
2) By minute:
amin :
access minute
cmin :
changed time
mmin :
modified time
eg:
-mmin +3 # 3
minutes ago
-mmin 3 #
Exactly 3 minutes ago
-mmin -3 #
within 3 minutes
eg: Find files that are modified 24 hours ago.
$ find . type f -mtime +24
String manipulation:
${#string}
expr
length $string
stringZ=abcABC123ABCabc
echo ${#stringZ} # 15
echo `expr length $stringZ` # 15
echo `expr "$stringZ" : '.*'` # 15
|
|
|
|
|
Length of Matching
Substring at Beginning of String
expr match "$string" '$substring'
expr
"$string" : '$substring'
stringZ=abcABC123ABCabc
# |------|
#
12345678
echo `expr match "$stringZ"
'abc[A-Z]*.2'` # 8
echo `expr "$stringZ" :
'abc[A-Z]*.2'` # 8
|
Index
expr index $string $substring
stringZ=abcABC123ABCabc
#
123456 ...
echo `expr index "$stringZ"
C12` # 6
# C position.
echo `expr index "$stringZ" 1c` # 3
# 'c' (in #3 position) matches before '1'.
|
Substring Extraction
Extracts substring from $string at $position.
${string:position:length}
:
Extracts $length characters of substring from $string at $position.
stringZ=abcABC123ABCabc
#
0123456789.....
#
0-based indexing.
echo ${stringZ:0} # abcABC123ABCabc
echo ${stringZ:1} # bcABC123ABCabc
echo ${stringZ:7} # 23ABCabc
echo ${stringZ:7:3} # 23A
# Three characters of substring.
# Is it possible to index from the right end
of the string?
echo ${stringZ:-4} # abcABC123ABCabc
# Defaults to full string, as in
${parameter:-default}.
# However . . .
echo ${stringZ:(-4)} # Cabc
echo ${stringZ: -4} # Cabc
# Now, it works.
# Parentheses or added space
"escape" the position parameter.
# Thank you, Dan Jacobson, for pointing this
out.
|
The position
and length arguments can be "parameterized," that is,
represented as a variable, rather than as a numerical constant.
If
the $string parameter is "*" or "@", then this
extracts a maximum of $length positional parameters, starting at $position.
echo ${*:2} # Echoes second and following
positional parameters.
echo ${@:2} # Same as above.
echo ${*:2:3} # Echoes three positional parameters,
starting at second.
|
expr
substr
$string $position $length
:
Extracts $length characters from $string starting
at $position.
stringZ=abcABC123ABCabc
#
123456789......
#
1-based indexing.
echo `expr substr $stringZ 1 2` # ab
echo `expr substr $stringZ 4 3` # ABC
|
expr
match "$string" '\($substring\)'
expr
"$string" : '\($substring\)'
Extracts $substring at beginning of $string, where $substring is a regular expression.
stringZ=abcABC123ABCabc
#
=======
echo `expr match "$stringZ"
'\(.[b-c]*[A-Z]..[0-9]\)'` # abcABC1
echo `expr "$stringZ" :
'\(.[b-c]*[A-Z]..[0-9]\)'` #
abcABC1
echo `expr "$stringZ" :
'\(.......\)'` #
abcABC1
# All of the above forms give an identical
result.
|
expr
match "$string" '.*\($substring\)'
Extracts $substring at end of
$string, where $substring is a regular expression.
Expr
"$string" : '.*\($substring\)'
Extracts $substring at end of $string, where $substring is a regular expression.
stringZ=abcABC123ABCabc
# ======
echo `expr match "$stringZ"
'.*\([A-C][A-C][A-C][a-c]*\)'` #
ABCabc
echo `expr "$stringZ" :
'.*\(......\)'` #
ABCabc
|
Substring Removal
${string#substring}
Deletes
shortest match of $substring from front of $string.
${string##substring}
Deletes
longest match of $substring from front of $string.
stringZ=abcABC123ABCabc
#
|----| shortest
#
|----------| longest
echo ${stringZ#a*C} # 123ABCabc
# Strip out shortest match between 'a' and
'C'.
echo ${stringZ##a*C} # abc
# Strip out longest match between 'a' and 'C'.
# You can parameterize the substrings.
X='a*C'
echo ${stringZ#$X} # 123ABCabc
echo ${stringZ##$X} # abc
# As above.
|
${string%substring}
Deletes shortest
match of $substring from back of $string.
For
example:
# Rename all filenames in $PWD with
"TXT" suffix to a "txt" suffix.
# For example, "file1.TXT" becomes
"file1.txt" . . .
SUFF=TXT
suff=txt
for i in $(ls *.$SUFF)
do
mv -f
$i ${i%.$SUFF}.$suff
# Leave unchanged everything *except* the
shortest pattern match
#+
starting from the right-hand-side of the variable $i . . .
done ### This could be condensed into a
"one-liner" if desired.
# Thank you, Rory Winston.
|
${string%%substring}
Deletes longest
match of $substring from back of $string.
stringZ=abcABC123ABCabc
# || shortest
#
|------------| longest
echo ${stringZ%b*c} # abcABC123ABCa
# Strip out shortest match between 'b' and
'c', from back of $stringZ.
echo ${stringZ%%b*c} # a
# Strip out longest match between 'b' and 'c',
from back of $stringZ.
|
This
operator is useful for generating filenames.
Substring Replacement
${string/substring/replacement}
Replace first match
of $substring with $replacement. [2]
${string//substring/replacement}
Replace all matches
of $substring with $replacement.
stringZ=abcABC123ABCabc
echo ${stringZ/abc/xyz} # xyzABC123ABCabc
# Replaces
first match of 'abc' with 'xyz'.
echo ${stringZ//abc/xyz} # xyzABC123ABCxyz
# Replaces all
matches of 'abc' with # 'xyz'.
echo
---------------
echo "$stringZ" # abcABC123ABCabc
echo
---------------
# The string
itself is not altered!
# Can the match and replacement strings be
parameterized?
match=abc
repl=000
echo ${stringZ/$match/$repl} # 000ABC123ABCabc
#
^ ^ ^^^
echo ${stringZ//$match/$repl} #
000ABC123ABC000
# Yes!
^ ^ ^^^ ^^^
echo
# What happens if no $replacement string is
supplied?
echo ${stringZ/abc} # ABC123ABCabc
echo ${stringZ//abc} # ABC123ABC
# A simple deletion takes place.
|
${string/#substring/replacement}
If $substring matches front
end of $string, substitute $replacement
for $substring.
${string/%substring/replacement}
If $substring matches back
end of $string, substitute $replacement
for $substring.
stringZ=abcABC123ABCabc
echo ${stringZ/#abc/XYZ} # XYZABC123ABCabc
# Replaces front-end match of 'abc' with
'XYZ'.
echo ${stringZ/%abc/XYZ} # abcABC123ABCXYZ
# Replaces
back-end match of 'abc' with 'XYZ'.
|
10.1.1. Manipulating strings using awk
A
Bash script may invoke the string manipulation facilities of awk
as an alternative to using its built-in operations.
Example
10-6. Alternate ways of extracting and locating substrings
#!/bin/bash
# substring-extraction.sh
String=23skidoo1
#
012345678 Bash
#
123456789 awk
# Note different string indexing system:
# Bash numbers first character of string as 0.
# Awk
numbers first character of string as 1.
$ echo ${String:2:4} # position 3 (0-1-2), 4
characters long
# skid
# Piping
an empty "echo" to awk gives it dummy input,
# and thus makes it unnecessary to supply a
filename.
# The awk equivalent of ${string:pos:length}
is substr(string,pos,length).
$ echo | awk '{ print
substr("'"${String}"'",3,4)}' # skid
#
The awk equivalent of "expr index" ...
$ echo | awk '{ print
index("'"${String}"'", "skid")}' # 3 (skid starts at position 3)
exit 0
|