Linux commands/shell
Prompt
date
cal
df
free
exit
pwd
cd
ls
file
less
Various system directories
cp
mv
mkdir
rm
ln
ln -s
type
which
help
--help
man
apropos
whatis
info
alias
unalias
cat
sort
uniq
grep
wc
head
tail
tee
echo
echo $((2 + 2))
echo $(($((5**2)) * 3))
echo $(((5**2) * 3))
echo Five divided by two equals $((5/2))
echo Front-{A,B,C}-Back
echo Number_{1..5}
echo {001..15}
88e9fe8514cd:~ shjabbar$ echo a{A{1,2},B{3,4}}b
aA1b aA2b aB3b aB4b
88e9fe8514cd:~ shjabbar$
echo $USER
printenv | less
ls -l $(which cp)
file $(ls -d /usr/bin/* | grep zip)
ls -l `which cp`
echo this is a test
echo "$USER $((2+2)) $(cal)"
88e9fe8514cd:Downloads shjabbar$ echo $(cal)
October 2019 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
88e9fe8514cd:Downloads shjabbar$ echo "$(cal)"
October 2019
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
88e9fe8514cd:Downloads shjabbar$ echo '$(cal)'
$(cal)
88e9fe8514cd:Downloads shjabbar$
88e9fe8514cd:Downloads shjabbar$ echo text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER
text /Users/shjabbar/shine.txt a b foo 4 shjabbar
88e9fe8514cd:Downloads shjabbar$ echo "text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER"
text ~/*.txt {a,b} foo 4 shjabbar
88e9fe8514cd:Downloads shjabbar$ echo 'text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER'
text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER
88e9fe8514cd:Downloads shjabbar$
sleep 10; echo -e "Time's up\a"
We could also do this:
sleep 10; echo "Time's up" $'\a'
8 – Advanced Keyboard Tricks (lot of keyboard tricks)
clear
history
ctrl-l to clear
Alt-* Insert all possible completions.
!string - Repeat last history list item starting with string.
!?string - Repeat last history list item containing string.
script
ctrl-c to stop script
9 – Permissions
id – Display user identity
chmod – Change a file's mode
u+x Add execute permission for the owner.
u-x
+x Add execute permission for the owner, group, and world. This is
Remove execute permission from the owner. equivalent to a+x.
umask – Set the default file permissions
su -
su
sudo
bash-3.2$ sudo -l
Matching Defaults entries for shjabbar on 88e9fe8514cd:
env_reset, env_keep+=BLOCKSIZE, env_keep+="COLORFGBG COLORTERM", env_keep+=__CF_USER_TEXT_ENCODING, env_keep+="CHARSET LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE", env_keep+="LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME", env_keep+="LINES COLUMNS",
env_keep+=LSCOLORS, env_keep+=SSH_AUTH_SOCK, env_keep+=TZ, env_keep+="DISPLAY XAUTHORIZATION XAUTHORITY", env_keep+="EDITOR VISUAL", env_keep+="HOME MAIL", lecture_file=/etc/sudo_lecture
User shjabbar may run the following commands on 88e9fe8514cd:
(ALL) ALL
(root) NOPASSWD: /usr/local/bin/elevate-admin
bash-3.2$
chown [owner][:[group]] file...
passwd
10 - Processes
ps
ps x
ps aux
top
jobs
fg
bg
ctrl-z
kill
kill -1
killall xlogo
pstree
vmstat
xload
tload
Part 2 Configuration and the Environment
11 - The Environment
printenv
printenv USER
set | less
The set command, when used without options or arguments, will display both the shell and environment variables, as well as any defined shell functions.
Unlike printenv, its output is courteously sorted in alphabetical order.
/etc/profile: A global configuration script that applies to all users.
~/.bash_profile: A user's personal startup file. This can be used to extend or override settings in the global configuration script.
~/.bash_login: If ~/.bash_profile is not found, bash attempts to read this script.
~/.profile: If neither ~/.bash_profile nor ~/.bash_login is found, bash attempts to read this file. This is the default in Debian-based distributions, such as Ubuntu.
/etc/bash.bashrc: A global configuration script that applies to all users.
~/.bashrc: A user's personal startup file. It can be used to extend or override settings in the global configuration script.
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
The export command tells the shell to make the contents of PATH available to child processes of this shell.
13 - Customizing the Prompt
[me@linuxbox ~]$ echo $PS1
[\u@\h \W]\$
[shjabbar@88e9fe8514cd.ant.amazon.com ~] bash-3.2$ echo $PS1
(\d \t)\n[\033[1;41m\u@\H\[\033[0m\] \w] \s-\v$
(Mon Nov 18 23:09:08)
[shjabbar@88e9fe8514cd.ant.amazon.com ~] bash-3.2$
14- Package management
Debian Style (.deb) Debian, Ubuntu, Linux Mint, Raspbian
Red Hat Style (.rpm) Fedora, CentOS, Red Hat Enterprise Linux, OpenSUSE
Distributions Low-Level Tools High-Level Tools
============= =============== ================
Debian style dpkg apt, apt-get, aptitude
Fedora, Red Hat Enterprise Linux, CentOS rpm yum, dnf
apt-get install package_name
yum install package_name
dpkg -i package_file
rpm -i package_file
apt-get remove package_name
yum erase package_name
15 - Storage Media
cat /etc/fstab
mount
tail -f /var/log/messages
sudo fdisk /dev/sdb
[me@linuxbox ~]$ sudo mkfs -t ext4 /dev/sdb1
mke2fs 2.23.2 (12-Jul-2011)
Filesystem label=
[me@linuxbox ~]$ sudo fsck /dev/sdb1
fsck 1.40.8 (13-Mar-2016)
dd if=input_file of=output_file [bs=block_size [count=blocks]]
dd if=/dev/sdb of=/dev/sdc
dd if=/dev/sdb of=flash_drive.img
cdrom commands
16 - Networking
ping
traceroute
ip a
netstat -ie
netstat -r
ssh
17 - Searching for files
locate
updatedb
find ~
find ~ -type d
find ~ -type f -name "*.JPG" -size +1M
find ~ ( -type f -not -perms 0600 ) -or ( -type d -not -perms 0700 ) -delete
find ~ ( -type f -not -perms 0600 ) -or ( -type d -not -perms 0700 ) -exec ls '{}' ';'
[me@linuxbox ~]$ mkdir -p playground/dir-{001..100}
[me@linuxbox ~]$ touch playground/dir-{001..100}/file-{A..Z}
18 - Archiving and Backup
gzip -tv foo.txt.gz
foo.txt.gz: OK
ls -l /etc | gzip > foo.txt.gz
gunzip -c foo.txt | less
zcat foo.txt.gz | less
zless
bzip2
bunzip2
bzcat
bunzip2 foo.txt.bz2
tar cf playground.tar playground
c Create an archive from a list of files and/or directories.
x Extract an archive.
r Append specified pathnames to the end of an archive
t List the contents of an archive.
tar xf archive.tar pathname
find playground -name 'file-A' | tar cf - --files- from=- | gzip > playground.tgz
find playground -name 'file-A' | tar czf playground.tgz -T -
find playground -name 'file-A' | tar cjf playground.tbz -T -
ssh remote-sys 'tar cf - Documents' | tar xf -
zip and unzip are pretty good and contain useful examples. However, the main use of these programs is for exchanging files with Windows systems
rsync options source destination
rsync -av playground foo
sudo rsync -av --delete /etc /home /usr/local /media/BigDisk/backup
sudo rsync -av --delete --rsh=ssh /etc /home /usr/local remote-sys:/backup
rsync -av –delete rsync://archive.linux.duke.edu/ fedora/linux/development/rawhide/Everything/x86_64/os/ fedora-devel
19 - Regular Expressions
grep
-i --ignore-case
-v --invert-match
-c --count
-l --files-with-matches
-L --files-without-match
-n --line-number
-h --no-filename
grep -h '.zip' dirlist*.txt
[me@linuxbox ~]$ grep -h '^zip$' dirlist*.txt
zip
[me@linuxbox ~]$ grep -i '^..j.r$' /usr/share/dict/words
Major
major
[me@linuxbox ~]$ grep -h '[bg]zip' dirlist*.txt
bzip2
bzip2recover
gzip
[me@linuxbox ~]$ grep -h '[^bg]zip' dirlist*.txt
bunzip2
gunzip
funzip
[me@linuxbox ~]$ grep -h '^[A-Z]' dirlist*.txt
MAKEDEV
ControlPanel
GET
POSIX meta characters - ^ $ . [ ] *
Extended Regular Expressions ( ) { } ? + |
[me@linuxbox ~]$ echo "AAA" | grep -E 'AAA|BBB'
AAA
#This expression will match the filenames in our lists that start with either bz, gz, or zip.
grep -Eh '^(bz|gz|zip)' dirlist*.txt
? - Match an Element Zero or One Time
* - Match an Element Zero or More Times
+ - Match an Element One or More Times
{ } - Match an Element a Specific Number of Times
[me@linuxbox ~]$ echo "(555) 123-4567" | grep -E '^\(?[0-9]{3}\)? [0- 9]{3}-[0-9]{4}$'
(555) 123-4567
find . -regex '.*[^-_./0-9a-zA-Z].*'
vim search: /([0-9]\{3\}) [0-9]\{3\}-[0-9]\{4\}
20 - Text Processing
cat -A foo.txt
^IThe quick brown fox jumped over the lazy dog. $
[me@linuxbox ~]$
[me@linuxbox ~]$ cat -ns foo.txt
1 The quick brown fox
2
3 jumped over the lazy dog.
[me@linuxbox ~]$
[me@linuxbox ~]$ sort > foo.txt
c
b
a
[me@linuxbox ~]$ cat foo.txt
a
b
c
sort file1.txt file2.txt file3.txt > final_sorted_list.txt
-b --ignore-leading-blanks
-f --ignore-case
-n --numeric-sort
-r --reverse
-k --key=field1[,field2]
-m --merge
-o --output=file
-t --field-separator=char
[me@linuxbox ~]$ du -s /usr/share/* | sort -nr | head
509940 /usr/share/locale-langpack
242660 /usr/share/doc
197560 /usr/share/fonts
[me@linuxbox ~]$ ls -l /usr/bin | sort -nrk 5 | head
-rwxr-xr-x 1 root root 8234216 2016-04-07 17:42 inkscape
-rwxr-xr-x 1 root root 8222692 2016-04-07 17:42 inkview
-rwxr-xr-x 1 root root 3746508 2016-03-07 23:45 gimp-2.4
[me@linuxbox ~]$ sort --key=1,1 --key=2n distros.txt
Fedora 5 03/20/2006
Fedora 6 10/24/2006
Fedora 7 05/31/2007
Fedora 8 11/08/2007
Fedora 9 05/13/2008
[me@linuxbox ~]$ sort -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt
Fedora 10 11/25/2008
Ubuntu 8.10 10/30/2008
SUSE 11.0 06/19/2008
[me@linuxbox ~]$ sort -t ':' -k 7 /etc/passwd | head
me:x:1001:1001:Myself,,,:/home/me:/bin/bash
root:x:0:0:root:/root:/bin/bash
dhcp:x:101:102::/nonexistent:/bin/false
sort foo.txt | uniq
sort foo.txt | uniq -c
cut -f 3 distros.txt | cut -c 7-10
cut -d ':' -f 1 /etc/passwd | head
[me@linuxbox ~]$ paste distros-dates.txt distros-versions.txt
11/25/2008 Fedora 10
10/30/2008 Ubuntu 8.10
06/19/2008 SUSE 11.0
05/13/2008 Fedora 9
[me@linuxbox ~]$ join distros-key-names.txt distros-key-vernums.txt | head
11/25/2008 Fedora 10
10/30/2008 Ubuntu 8.10
06/19/2008 SUSE 11.0
comm
diff
patch
[me@linuxbox ~]$ diff -Naur file1.txt file2.txt > patchfile.txt
[me@linuxbox ~]$ patch < patchfile.txt
patching file file1.txt
echo "lowercase letters" | tr a-z A-Z
tr -d '\r' < dos_file > unix_file
[me@linuxbox ~]$ echo "aaabbbccc" | tr -s ab
abccc
[me@linuxbox ~]$ echo "front" | sed 's/front/back/'
back
#line number based
[me@linuxbox ~]$ echo "front" | sed '2s/front/back/'
front
sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{4\}\ )$/\3-\1-\2/' distros.txt
We now have three subexpressions ()
sed -f distros.sed distros.txt
[me@linuxbox ~]$ sed -i 's/lazy/laxy/; s/jumped/jimped/' foo.txt
The sed option -i tells sed to edit the file “in-place,”
aspell check foo.txt
aspell -H check foo.txt
21 - Formatting Output
nl
[me@linuxbox ~]$ nl distros.txt | head
1 SUSE 10.2
2 Fedora 10
3 SUSE 11.0
nl markup used in sed
\:\:\: Start of logical page header
\:\: Start of logical page body
\: Start of logical page footer
[me@linuxbox ~]$ echo "The quick brown fox jumped over the lazy dog." | fold -w 12 -s
The quick
brown fox
jumped over
the lazy
dog.
[me@linuxbox ~]$ fmt -cw 50 fmt-info.txt
`fmt' reads from the specified FILE arguments
(or standard input if none are given), and writes
to standard output.
[me@linuxbox ~]$ printf "I formatted the string: %s\n" foo
I formatted the string: foo
[me@linuxbox ~]$ printf "I formatted '%s' as a string.\n" foo
I formatted 'foo' as a string.
groff
zcat /usr/share/man/man1/ls.1.gz | groff -mandoc -T ascii | head
zcat /usr/share/man/man1/ls.1.gz | groff -mandoc > ~/Desktop/ls.ps
22 – Printing
skipping
23 – Compiling Programs
skipping
24 – Writing Your First Script
#!/bin/bash
# This is our first script.
echo 'Hello World!'
25 – Starting a Project
mv "$filename" "${filename}1"
#-r (read- only) option
declare -r TITLE="Page Title"
variable=value
CURRENT_TIME="$(date +"%x %r %Z")"
TIMESTAMP="Generated $CURRENT_TIME, by $USER"
Here Documents
command << token
text
token
cat << _EOF_
<html>
<head>
<title>$TITLE</title>
</head>
<body>
<h1>$TITLE</h1>
<p>$TIMESTAMP</p>
</body>
</html>
_EOF_
If we change the redirection operator from << to <<-, the shell will ignore leading tab
26 – Top-Down Design
function step2 {
echo step 2
return
}
echo step 1
step2
echo step 3
#!/bin/bash
# local-vars: script to demonstrate local variables foo=0 # global variable foo
funct_1 () {
local foo # variable foo local to funct_1
foo=1
echo "funct_1: foo = $foo"
}
27 – Flow Control: Branching with if
x=5
if [ "$x" -eq 5 ]; then
echo "x equals 5."
else
echo "x does not equal 5."
fi
if [ “$x” -eq 5 ]; then echo "equals 5"; else echo "does not equal 5"; fi
(19-12-15 15:34:46) <0> [~/workbook]
dev-dsk-shjabbar-2a-70ace2a6 % echo $?
0
(19-12-15 15:34:50) <0> [~/workbook]
dev-dsk-shjabbar-2a-70ace2a6 % ls /ere
ls: cannot access /ere: No such file or directory
(19-12-15 15:34:56) <2> [~/workbook]
dev-dsk-shjabbar-2a-70ace2a6 % echo $?
2
(19-12-15 15:34:59) <0> [~/workbook]
dev-dsk-shjabbar-2a-70ace2a6 %
[me@linuxbox ~]$ true
[me@linuxbox ~]$ echo $?
0
[me@linuxbox ~]$ false
[me@linuxbox ~]$ echo $?
1
[me@linuxbox ~]$ if true; then echo "It's true."; fi
It's true.
[me@linuxbox ~]$ if false; then echo "It's true."; fi
[me@linuxbox ~]$
dev-dsk-shjabbar-2a-70ace2a6 % if true;false;true;then echo "It's true."; fi
It's true.
The test and [ commands support a wide range of useful expressions and tests.
test_file () {
# test-file: Evaluate the status of a file
FILE=~/.bashrc
if [ -e "$FILE" ]; then
if [ -f "$FILE" ]; then
echo "$FILE is a regular file."
fi
if [ -d "$FILE" ]; then
echo "$FILE is a directory."
fi
if [ -r "$FILE" ]; then
echo "$FILE is readable."
fi
if [ -w "$FILE" ]; then
echo "$FILE is writable."
fi
if [ -x "$FILE" ]; then
echo "$FILE is executable/searchable."
fi
else
echo "$FILE does not exist"
return 1
fi
}
#!/bin/bash
# test-string: evaluate the value of a string
ANSWER=maybe
if [ -z "$ANSWER" ]; then
echo "There is no answer." >&2
exit 1
fi
if [ "$ANSWER" = "yes" ]; then
echo "The answer is YES."
elif [ "$ANSWER" = "no" ]; then
echo "The answer is NO."
elif [ "$ANSWER" = "maybe" ]; then
echo "The answer is MAYBE."
else
echo "The answer is UNKNOWN."
fi
#!/bin/bash
# test-integer: evaluate the value of an integer.
INT=-5
if [ -z "$INT" ]; then
echo "INT is empty." >&2
exit 1
if [ "$INT" -eq 0 ]; then
echo "INT is zero."
else
if [ "$INT" -lt 0 ]; then
echo "INT is negative."
else
echo "INT is positive."
fi
if [ $((INT % 2)) -eq 0 ]; then
echo "INT is even."
else
echo "INT is odd."
fi
fi
[[ ]]
#!/bin/bash
# test-integer2: evaluate the value of an integer.
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
if [ "$INT" -eq 0 ]; then
echo "INT is zero."
fi
fi
The ~ is actually part of the operator =~ which performs a regular expression match of the string to its left to the extended regular expression on its right.
[[ "string" =~ pattern ]]
[[ ]]
[me@linuxbox ~]$ FILE=foo.bar
[me@linuxbox ~]$ if [[ $FILE == foo.* ]]; then > echo "$FILE matches pattern 'foo.*'"
> fi
foo.bar matches pattern 'foo.*'
(( ))
# test-integer2a: evaluate the value of an integer.
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
if ((INT == 0)); then
echo "INT is zero."
else
if ((INT < 0)); then
echo "INT is negative."
else
echo "INT is positive."
fi
if (( ((INT % 2)) == 0)); then
echo "INT is even."
else
echo "INT is odd."
fi
fi else
echo "INT is not an integer." >&2
exit 1 fi
Operation test [[ ]] and (( ))
========= ==== ===============
AND -a &&
OR -o ||
NOT ! !
AND and negation
[[ ]]
AND and negation
if [[ "$INT" -ge "$MIN_VAL" && "$INT" -le "$MAX_VAL" ]]; then
echo "$INT is within $MIN_VAL to $MAX_VAL."
else
echo "$INT is out of range."
fi
if [[ ! ("$INT" -ge "$MIN_VAL" && "$INT" -le "$MAX_VAL") ]]; then
echo "$INT is outside $MIN_VAL to $MAX_VAL."
else
echo "$INT is in range."
fi
OR
[ ]
if [ "$INT" -ge "$MIN_VAL" -a "$INT" -le "$MAX_VAL" ]; then echo "$INT is within $MIN_VAL to $MAX_VAL."
else
echo "$INT is out of range."
fi
if [ ! \( "$INT" -ge "$MIN_VAL" -a "$INT" -le "$MAX_VAL" \) ];
then
echo "$INT is outside $MIN_VAL to $MAX_VAL."
else
echo "$INT is in range."
fi
command1 && command2
command1 || command2
[me@linuxbox ~]$ [[ -d temp ]] || mkdir temp
[ -d temp ] || exit 1
28 – Reading Keyboard Input
echo -n "Please enter an integer -> "
read int
#!/bin/bash
# read-multiple: read multiple values from keyboard
echo -n "Enter one or more values > "
read var1 var2 var3 var4 var5
echo "var1 = '$var1'"
echo "var2 = '$var2'"
echo "var3 = '$var3'"
echo "var4 = '$var4'"
echo "var5 = '$var5'"
read -e -p "What is your user name? " -i $USER
echo "You answered: '$REPLY'"
if read -t 10 -sp "Enter secret passphrase > " secret_pass; then
echo -e "\nSecret passphrase = '$secret_pass'"
else
echo -e "\nInput timed out" >&2
exit 1
fi
IFS=":" read user pw uid gid name home shell <<< "1:2:3"
dev-dsk-shjabbar-2a-70ace2a6 % print $user $pw $uid
1 2 3
[[ -z "$REPLY" ]] && invalid_input
(( "$(echo "$REPLY" | wc -w)" > 1 )) && invalid_input
Validating Input
Menus
29 – Flow Control: Looping with while / until
while commands; do commands; done
#!/bin/bash
# while-count: display a series of numbers
count=1
while [[ "$count" -le 5 ]]; do
echo "$count"
count=$((count + 1))
done
echo "Finished."
#!/bin/bash
# until-count: display a series of numbers
count=1
until [[ "$count" -gt 5 ]]; do echo "$count"
count=$((count + 1))
done
echo "Finished."
dev-dsk-shjabbar-2a-70ace2a6 % while ls; do
while> sleep 3
while> done
bash-howto if.sh read.sh shell_function.sh while
bash-howto if.sh read.sh shell_function.sh while
bash-howto if.sh read.sh shell_function.sh while
bash-howto if.sh read.sh shell_function.sh while
bash-howto if.sh read.sh shell_function.sh while
^C%
(19-12-16 6:32:25) <130> [~/workbook]
dev-dsk-shjabbar-2a-70ace2a6 %
#!/bin/bash
# while-read: read lines from a file
while read distro version release; do
printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
"$distro" \
"$version" \
"$release"
done < distros.txt
#!/bin/bash
# while-read2: read lines from a file
sort -k 1,1 -k 2n distros.txt | while read distro version release; do
printf "Distro: %s\tVersion: %s\tReleased: %s\n" \
"$distro" \
done
30 – Troubleshooting
#!/bin/bash -x
# trouble: script to demonstrate common errors
number=1
if [ $number = 1 ]; then
echo "Number is equal to 1."
else
echo "Number is not equal to 1."
fi
[me@linuxbox ~]$ trouble
+ number=1
+ '[' 1 = 1 ']'
+ echo 'Number is equal to 1.'
Number is equal to 1.
#!/bin/bash
# trouble: script to demonstrate common errors
number=1
set -x # Turn on tracing
if [ $number = 1 ]; then
echo "Number is equal to 1."
else
echo "Number is not equal to 1."
fi
set +x # Turn off tracing
31 – Flow Control: Branching with case
case word in
[pattern [| pattern]...) commands ;;]...
esac
case "$REPLY" in
q|Q) echo "Program terminated."
exit
;;
a|A) echo "Hostname: $HOSTNAME"
uptime
;; b|B) df -h
;;
c|C) if [[ "$(id -u)" -eq 0 ]]; then
echo "Home Space Utilization (All Users)"
du -sh /home/*
else
echo "Home Space Utilization ($USER)"
du -sh "$HOME"
fi
;;
*) echo "Invalid entry" >&2
exit 1
;; esac
case "$REPLY" in
0) echo "Program terminated."
exit
;;
esac
32 – Positional Parameters
[me@linuxbox ~]$ posit-param a b c d
$0 = /home/me/bin/posit-param
$1 = a
$2 = b
$3 = c
$4 = d
$5 =
$6 =
$7 =
$8 =
$9 =
Note: You can actually access more than nine parameters using parameter expan- sion.
To specify a number greater than nine, surround the number in braces as in ${10}, ${55}, ${211}, and so on.
Number of arguments: $#
[me@linuxbox ~]$ posit-param a b c d
Number of arguments: 4
$0 = /home/me/bin/posit-param
$1 = a
$2 = b
$3 = c
$4 = d
$5 =
$6 =
$7 =
$8 =
$9 =
#!/bin/bash
# posit-param2: script to display all arguments
count=1
while [[ $# -gt 0 ]]; do
echo "Argument $count = $1"
count=$((count + 1))
shift
done
[me@linuxbox ~]$ posit-param2 a b c d
Argument 1 = a
Argument 2 = b
Argument 3 = c
Argument 4 = d
PROGNAME="$(basename "$0")"
echo "$FUNCNAME: usage: $FUNCNAME file" >&2
file_info () {
# file_info: function to display file information
if [[ -e "$1" ]]; then
echo -e "\nFile Type:"
file "$1"
echo -e "\nFile Status:"
stat "$1"
else
echo "$FUNCNAME: usage: $FUNCNAME file" >&2
return 1
fi }
$* Expands into the list of positional parameters, starting with 1.
When surrounded by double quotes, it expands into a double-quoted string
containing all of the positional parameters, each separated by the first
character of the IFS shell variable (by default a space character).
$@ Expands into the list of positional parameters, starting with 1.
When surrounded by double quotes, it expands each positional
parameter into a separate word as if it was surrounded by double quotes.
Always use "$@"
#!/bin/bash
# posit-params3: script to demonstrate $* and $@
print_params () {
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$3 = $3"
echo "\$4 = $4"
}
pass_params () {
echo -e "\n" '$* :'; print_params $*
echo -e "\n" '"$*" :'; print_params "$*"
echo -e "\n" '$@ :'; print_params $@
echo -e "\n" '"$@" :'; print_params "$@"
}
pass_params "word" "words with spaces"
[me@linuxbox ~]$ posit-param3
$* :
$1 = word
$2 = words
$3 = with
$4 = spaces
"$*" :
$1 = word words with spaces
$2 =
$3 =
$4 =
$@ :
$1 = word
$2 = words
$3 = with
$4 = spaces
"$@" :
$1 = word
$2 = words with spaces
$3 =
$4 =
usage () {
echo "$PROGNAME: usage: $PROGNAME [-f file | -i]"
return
}
# process command line options
interactive=
filename=
while [[ -n "$1" ]]; do
case "$1" in
-f | --file) shift
filename="$1"
;;
-i | --interactive) interactive=1
;;
-h | --help) usage
exit
;;
*) usage >&2
exit 1
;;
esac
done
33 – Flow Control: Looping with for
for variable [in words]; do
commands
done
for i in {A..D}; do echo $i; done
for i in distros*.txt; do echo "$i"; done
for (( expression1; expression2; expression3 )); do
commands
done
#!/bin/bash
# simple_counter: demo of C style for command
for (( i=0; i<5; i=i+1 )); do
echo $i
done
34 – Strings and Numbers
[me@linuxbox ~]$ echo "${a}_file"
${11}
${parameter:-word}
[me@linuxbox ~]$ foo=
[me@linuxbox ~]$ echo ${foo:-"substitute value if unset"}
substitute value if unset
[me@linuxbox ~]$ echo $foo
[me@linuxbox ~]$ foo=bar
[me@linuxbox ~]$ echo ${foo:-"substitute value if unset"}
bar
[me@linuxbox ~]$ echo $foo
${parameter:=word}
[me@linuxbox ~]$ foo=
[me@linuxbox ~]$ echo ${foo:="default value if unset"}
default value if unset
[me@linuxbox ~]$ echo $foo
default value if unset
[me@linuxbox ~]$ foo=bar
[me@linuxbox ~]$ echo ${foo:="default value if unset"}
bar
[me@linuxbox ~]$ echo $foo
bar
${parameter:?word}
[me@linuxbox ~]$ foo=
[me@linuxbox ~]$ echo ${foo:?"parameter is empty"}
bash: foo: parameter is empty
[me@linuxbox ~]$ echo $?
1
[me@linuxbox ~]$ foo=bar
[me@linuxbox ~]$ echo ${foo:?"parameter is empty"}
bar
[me@linuxbox ~]$ echo $?
0
${parameter:+word}
If parameter is unset or empty, the expansion results in nothing. If parameter is not empty, the value of word is substituted for parameter; however, the value of parameter is not changed.
[me@linuxbox ~]$ foo=
[me@linuxbox ~]$ echo ${foo:+"substitute value if set"}
[me@linuxbox ~]$ foo=bar
[me@linuxbox ~]$ echo ${foo:+"substitute value if set"}
substitute value if set
[me@linuxbox ~]$ foo="This string is long."
[me@linuxbox ~]$ echo "'$foo' is ${#foo} characters long."
'This string is long.' is 20 characters long.
[me@linuxbox ~]$ foo="This string is long."
[me@linuxbox ~]$ echo ${foo:5}
string is long.
[me@linuxbox ~]$ echo ${foo:5:6}
string
[me@linuxbox ~]$ foo="This string is long."
[me@linuxbox ~]$ echo ${foo: -5}
long.
[me@linuxbox ~]$ echo ${foo: -5:2}
lo
${parameter#pattern}
${parameter##pattern}
[me@linuxbox ~]$ foo=file.txt.zip
[me@linuxbox ~]$ echo ${foo#*.}
txt.zip
[me@linuxbox ~]$ echo ${foo##*.}
zip
${parameter%pattern}
${parameter%%pattern}
[me@linuxbox ~]$ foo=file.txt.zip
[me@linuxbox ~]$ echo ${foo%.*}
file.txt
[me@linuxbox ~]$ echo ${foo%%.*}
file
[me@linuxbox ~]$ foo=file.txt.zip
[me@linuxbox ~]$ echo ${foo%.*}
file.txt
[me@linuxbox ~]$ echo ${foo%%.*}
file
${parameter/pattern/string}
${parameter//pattern/string}
${parameter/#pattern/string}
${parameter/%pattern/string}
[me@linuxbox ~]$ foo=JPG.JPG
[me@linuxbox ~]$ echo ${foo/JPG/jpg}
jpg.JPG
[me@linuxbox ~]$ echo ${foo//JPG/jpg}
jpg.jpg
[me@linuxbox ~]$ echo ${foo/#JPG/jpg}
jpg.JPG
[me@linuxbox ~]$ echo ${foo/%JPG/jpg}
JPG.jpg
#!/bin/bash
# ul-declare: demonstrate case conversion via declare
declare -u upper
declare -l lower
if [[ $1 ]]; then
upper="$1"
lower="$1"
echo "$upper"
echo "$lower"
fi
#!/bin/bash
# ul-param: demonstrate case conversion via parameter expansion
if [[ "$1" ]]; then
echo "${1,,}"
echo "${1,}"
echo "${1^^}"
echo "${1^}"
fi
[me@linuxbox ~]$ ul-param aBc
abc
aBc
ABC
ABc
All c logical and arithmetic operation in (( --- ))
bc
35 – Arrays
declare -a a
Using the -a option, this example of declare creates the array a.
[me@linuxbox ~]$ days=(Sun Mon Tue Wed Thu Fri Sat)
[me@linuxbox ~]$ days=([0]=Sun [1]=Mon [2]=Tue [3]=Wed [4]=Thu [5]=Fri [6]=Sat)
printf "%02d\t%d\t%02d\t%d\n" \
"$i" \
"${hours[i]}" \
"$j" \
"${hours[j]}"
[me@linuxbox ~]$ animals=("a dog" "a cat" "a fish")
[me@linuxbox ~]$ for i in ${animals[*]}; do echo $i; done
a
dog
a
cat
a
fish
[me@linuxbox ~]$ for i in ${animals[@]}; do echo $i; done
a
dog
a
cat
a
fish
[me@linuxbox ~]$ for i in "${animals[*]}"; do echo $i; done
a dog a cat a fish
[me@linuxbox ~]$ for i in "${animals[@]}"; do echo $i; done
a dog
a cat
a fish
[me@linuxbox ~]$ a[100]=foo
[me@linuxbox ~]$ echo ${#a[@]} # number of array elements
1
[me@linuxbox ~]$ echo ${#a[100]} # length of element 100
3
${!array[*]}
${!array[@]}
[me@linuxbox ~]$ foo=([2]=a [4]=b [6]=c)
[me@linuxbox ~]$ for i in "${foo[@]}"; do echo $i; done
a
b
c
[me@linuxbox ~]$ for i in "${!foo[@]}"; do echo $i; done
2
4
6
+=
[me@linuxbox ~]$ foo=(a b c)
[me@linuxbox ~]$ echo ${foo[@]}
a b c
[me@linuxbox ~]$ foo+=(d e f)
[me@linuxbox ~]$ echo ${foo[@]}
a b c d e f
unset foo
unset 'foo[2]'
declare -A colors
colors["red"]="#ff0000"
colors["green"]="#00ff00"
colors["blue"]="#0000ff"
echo ${colors["blue"]}
36 – Exotica
{ ls -l; echo "Listing of foo.txt"; cat foo.txt; } | lpr
Process Substitution
<(list)
>(list)
read < <(echo "foo")
echo $REPLY
[me@linuxbox ~]$ echo <(echo "foo")
/dev/fd/63
#!/bin/bash
# trap-demo: simple signal handling demo
trap "echo 'I am ignoring you.'" SIGINT SIGTERM
for i in {1..5}; do
echo "Iteration $i of 5"
sleep 5
done
[me@linuxbox ~]$ trap-demo Iteration 1 of 5 Iteration 2 of 5
^CI am ignoring you. Iteration 3 of 5
^CI am ignoring you.
Iteration 4 of 5
Iteration 5 of 5
tempfile=$(mktemp /tmp/foobar.$$.XXXXXXXXXX)
88e9fe8514cd:~ shjabbar$ tempfile=$(mktemp /tmp/foobar.$$.XXXXXXXXXX)
88e9fe8514cd:~ shjabbar$ echo $tempfile
/tmp/foobar.28696.XnAEcahBws
88e9fe8514cd:~ shjabbar$
Asynchronous Execution
$! shell parameter, which will always contain the process ID of the last job put into the background.
Named Pipes
[me@linuxbox ~]$ mkfifo pipe1
[me@linuxbox ~]$ ls -l pipe1
prw-r--r-- 1 me me 0 2009-07-17 06:41 pipe1
Terminal 1:
[me@linuxbox ~]$ ls -l > pipe1
Terminal 2:
[me@linuxbox ~]$ cat < pipe1