BASH help
The Linux Command Line: https://wiki.lib.sun.ac.za/images/c/ca/TLCL-13.07.pdf
Template
————————
#!/bin/bash
# Replace with description and/or purpose of this shell script
GLOBAL_VAR1="one"
GLOBAL_VAR2="two"
function function_one() {
local LOCAL_VAR1="one"
# Replace with function code
return 0
}
# Main body of the shell script starts here
# Exit with an explicit status
exit 0
————————
Regular Expression
Special characters —> . * []. ^. $ {}. \. +. ? |. ()
^ starting
$ ending
[[:alpha:]]
[[:digit:]]
() grouping —> Sat(urday)?
Tests
[ ] numeric comparison -eq , -ge, -lt , …
[ ] string comparision - = , != , < , > -n (greater than length zero), -z (length zero)
() -> sub shell
(( )) -> is (( expression )). operations—> val++ val— ! ~ ** << >> & | && ||
[[ ]] -> is [[ advanced string operations ]]
Files
-d - file is directory
-e - file exists
-f - file exists and its a file
-s - file exists and not empty
-O - file exists and owned by me
File -nt file - newer than -ot older than
[ condition 1 ] && [ condition 2 ]
[ condition 1 ] || [ condition 2 ]
Reading from a file
cat file | while read line
do
echo $line
done
Structured commands
If test $DEBUG
then
<<>>>
else
<<<>>>
fi
Exit Status
echo $?
Trapping signal
trap commands signal
trap “echo shine” SIGINT
trap -- SIGINT
sed
sed ’s/test/trial/‘ data.txt
Pattern matching and delete
sed ‘/shine/d’
awk
awk ‘{print “Hello World”}’
awk -F: ‘{print $1}’ file.txt
{$4=“shine”; print $0}
awk ‘BEGIN {print “Start”} {print $0} END {print “End”}’ data3.txt
Marker
shjabbar@3c063015fbe4 Downloads % cat << EOF
heredoc> This is Shine
heredoc> How are you ?
heredoc> EOF
This is Shine
How are you ?
shjabbar@3c063015fbe4 Downloads %
Array
https://opensource.com/article/18/5/you-dont-know-bash-intro-bash-arrays
Definition:
bash-3.2$ mytest=(zero one two three four)
bash-3.2$ echo $mytest
zero
Print n-th variable:
bash-3.2$ echo ${mytest[2]}
two
Print whole array variable:
bash-3.2$ echo ${mytest[*]}
zero one two three four
bash-3.2$
bash-3.2$
bash-3.2$ mytest[2]=seven
bash-3.2$ echo ${mytest[2]}
seven
bash-3.2$
bash-3.2$ unset mytest[2]
bash-3.2$
bash-3.2$ echo ${mytest[2]}
bash-3.2$ echo ${mytest[*]}
zero one three four
bash-3.2$
bash-3.2$ unset mytest
bash-3.2$ echo ${mytest[*]}
bash-3.2$
Subshell
Using a list of commands in background
(sleep 2; echo "Woke up, Now going to sleep.."; sleep 2)&
Sort
Sort k-th element numerically
sort -t ':' -k 3 -n /etc/passwd
Grep
Get count of match
grep -c t /etc/passwd
Grep multiple fields
grep -e root -e _timed /etc/passwd
Cat
With line number
cat -n schema
shjabbar@3c063015fbe4 Downloads % cat -n schema | head
1 {
2 "id": "http://json-schema.org/draft-04/schema#",
Read
read -p "Enter the extension that needs to be backed up " EXTENSION
Date
88e9fe8514cd:shell shjabbar$ date +%F
2021-09-07
88e9fe8514cd:shell shjabbar$ date +%Y
2021
88e9fe8514cd:shell shjabbar$ date +%y
21
88e9fe8514cd:shell shjabbar$
Seq
88e9fe8514cd:shell shjabbar$ seq -w 02 2 18
02
04
06
08
Declare
$ declare -i x=10
$ echo $x
10
$ x=ok
$ echo $x
0
$ x=15
$ echo $x
15
Case
case "$1" in
start|START)
echo "Command is start"
;;
stop|STOP)
echo "Command is stop"
;;
*)
echo "Usage: $0 start|stop"
;;
esac
Shift
88e9fe8514cd:shell shjabbar$ cat shift.sh
#!/bin/bash
# total number of command-line arguments
echo "Total arguments passed are: $#"
# $* is used to show the command line arguments
echo "The arguments are: $*"
echo "The First Argument is: $1"
shift 2
echo "The First Argument After Shift 2 is: $1"
shift
echo "The First Argument After Shift is: $1"
88e9fe8514cd:shell shjabbar$ ./shift.sh shine mohamed jabbar puthiyaveettil house
Total arguments passed are: 5
The arguments are: shine mohamed jabbar puthiyaveettil house
The First Argument is: shine
The First Argument After Shift 2 is: jabbar
The First Argument After Shift is: puthiyaveettil
88e9fe8514cd:shell shjabbar$
Logger
(21-09-10 6:00:34) <0> [/var/log]
dev-dsk-shjabbar-2a-b6139a9a % pwd
/var/log
(21-09-10 6:00:37) <0> [/var/log]
dev-dsk-shjabbar-2a-b6139a9a % ls user.log
user.log
(21-09-10 6:00:39) <0> [/var/log]
dev-dsk-shjabbar-2a-b6139a9a % logger "Message" -s -t myscript -i
myscript[32594]: Message
(21-09-10 6:00:46) <0> [/var/log]
dev-dsk-shjabbar-2a-b6139a9a %
Debugging
#/bin/bash -x
Or
set -x
<commands>
set +x
-e option to stop at error
-v option to print shell command as it is
-x option to print shell command after expansion and substitution
DEBUG=true
If $DEBUG
then
<<>>>
Else
<<<>>>
Fi
PS4=‘+ ${BASH_SOURCE}:${LINENO}:$FUNCNAME[0]}()
BASH tricks:
Repeat command (previous command)
!!
!a
!^
!$
!!:3
^old_string^new_string
^old_string^new_string:&
^remove_string
Current command
!#
!#:1
To record a session
script
exit
Clear history
history -c
Strip out blank or comments:
grep -E -v "^#|^$" changename.sh
Remote VIM (pretty cool)
vim scp://dev-dsk-shjabbar-2a-b6139a9a.us-west-2.amazon.com//home/shjabbar/get_snitch_graph
Print out as a table / column:
column -t
88e9fe8514cd:shell shjabbar$ mount | column -t
/dev/disk1s5 on / (apfs, local, read-only, journaled)
devfs on /dev (devfs, local, nobrowse)
Less with color:
grep gp_host_names get_snitch_graph
| less -R
Preserve color when piping to grep
—color=never
ls -l --color=always | grep get_ --color=never
Append text to file using sudo
echo $ENVIRONMENT | sudo tee -a /etc/motd
Display block of strings
awk '/Shadow/,/edit/' exercise4.sh
Delete block of strings
sed '/Shadow/,/edit/d' exercise4.sh
Remove a character or a set
cat exercise4.sh | tr -d [aeiou]
uniq -c
Get your public IP using curl
curl ifconfig.me/ip
204.246.162.45
Open network ports:
lsof -Pni
dev-dsk-shjabbar-2a-b6139a9a % sudo lsof -Pni
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
unbound 2759 named 3u IPv4 1622 0t0 UDP 127.0.0.1:53
Send mail
mail shjabbar@amazon.com
echo "Isn't this great" | mail -s "Test mail 2" -a get_snitch_graph shjabbar@amazon.com
dev-dsk-shjabbar-2a-b6139a9a % mail shjabbar@amazon.com
Subject: Test mail
Isn't this great
EOT
(21-09-19 5:44:37) <0> [~]
dev-dsk-shjabbar-2a-b6139a9a %
Create an SSH tunnel:
ssh -N -L local-port-opened-in-local-host:end-host:end-port remote-host-where-the-connection-will-be-initiated
ssh -N -L 8000:localhost:80 linuxserver
Simplifying multi-hop SSH
In .ssh/config
# Configuration for CPT
host *.cpt*.amazon.com *.cpt*.amazon.com. *.cpt? *.cpt??
ProxyCommand ssh bastion-cpt.amazon.com nc %h %p
Download webpage:
wget
curl -o file.html www.google.com
Read:
read VAR
read -n 1 VAR
read -p “Enter Value: “ VAR
Sum a column:
awk '{sum += $3} END {print sum}'
2021-09-21-05:10:29 big-mac-prod-tools-cmh-cmh52-50001.cmh50 cmh52:prod > df 2> /dev/null | awk '{sum += $3} END {print sum}'
118810236
2021-09-21-05:10:58 big-mac-prod-tools-cmh-cmh52-50001.cmh50 cmh52:prod >
Automatic Yes:
yes | command
Pkill:
pkill -9 httpd
Sort process with memory usage:
ps aux | sort -nk 4 | tail -5 | cut -c1-140
Make a quick backup
cp cscope.files{,.bak}
Sequence:
echo 10.0.0.{0..7}
10.0.0.0 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.5 10.0.0.6 10.0.0.7
Truncate a file:
> file
cat /dev/null > file
Create multiple directory:
mkdir {1..4}
Delete empty directory
find . -type d -empty -delete
List of all files with matching string
grep -rl bash *
Recursive ls:
ls -lR
find . -type f -ls
Replace string recursively with backup
find . -type f -iname "*.sh" -exec sed -i.bak 's/echo/ECHO/g' {} \;
Print Nth line:
awk 'NR==4' exercise4.sh
cat exercise4.sh | awk 'NR==4'
Convert text to image
sudo yum install ImageMagick
echo shine | convert label:@- hine.png
FOR loop
for VARIABLE in 1 2 3 4 5 .. N
do
command1
command2
commandN
done
for (( a = 1; a < 10; a++ ))
for (( a = 1, b = 10; a < 10; a++, b— ))
break
continue
Directory Name and base name
(21-10-07 21:04:28) <0> [~]
dev-dsk-shjabbar-2a-b6139a9a % basename bin/cscope.sh
cscope.sh
(21-10-07 21:04:41) <0> [~]
dev-dsk-shjabbar-2a-b6139a9a % man basename
(21-10-07 21:06:08) <0> [~]
dev-dsk-shjabbar-2a-b6139a9a % dirname bin/cscope.sh
bin
(21-10-07 21:06:16) <0> [~]
dev-dsk-shjabbar-2a-b6139a9a %
Function Parameters
shjabbar@3c063015fbe4 shell % cat rest_arg.sh
#!/usr/bin/env bash
all_args=$@
first_arg=$1
second_args=$2
rest_args=("${all_args[@]:2}")
shift
all_args_after_shift=$@
echo "All arguments - \$@ - $all_args"
echo "All arguments after shift - \$@ - $all_args_after_shift"
echo "Rest of the arguments - (\"\${all_args[@]:2}\") - ${rest_args[@]}"
shjabbar@3c063015fbe4 shell % ./rest_arg.sh 1 2 3 4 5 6 6
All arguments - $@ - 1 2 3 4 5 6 6
All arguments after shift - $@ - 2 3 4 5 6 6
Rest of the arguments - ("${all_args[@]:2}") - 2 3 4 5 6 6
shjabbar@3c063015fbe4 shell %
Checks
-n non-zero length
-z zero length
-f file exists
Not new line:
echo -n Dg Dg
command << marker
Dish’s
marker
Shopt
shopt -s nullglob