UNIX/Linux Shell Scripting: Difference between revisions
Lsokolowski1 (talk | contribs) |
Lsokolowski1 (talk | contribs) |
||
(6 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
;title: UNIX/Linux Shell Scripting | ;title: UNIX/Linux Shell Scripting | ||
;author: Lukasz Sokolowski (NobleProg Ltd) | ;author: Lukasz Sokolowski (NobleProg Ltd) | ||
== UNIX/Linux Shell Scripting == | == UNIX/Linux Shell Scripting == | ||
Line 13: | Line 12: | ||
{{Draft}} | {{Draft}} | ||
== Review of Basics - optional | == Review of Basics - optional == | ||
=== Files | === Files === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
touch filo.txt | touch filo.txt | ||
echo first line > filo1.txt | echo first line > filo1.txt | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Directories and Processes | |||
=== Directories and Processes === | |||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
mkdir diro | mkdir diro | ||
Line 27: | Line 27: | ||
top | top | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Displaying Directories - ls | === Displaying Directories - ls === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
ls -la | ls -la | ||
Line 35: | Line 35: | ||
ls -S | ls -S | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Getting Help - man, info | === Getting Help - man, info === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
--help | --help | ||
Line 50: | Line 50: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Displaying Files - cat, more | === Displaying Files - cat, more === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cat filo.txt | cat filo.txt | ||
Line 59: | Line 59: | ||
less internal options h, /, ? | less internal options h, /, ? | ||
=== Simple Commands | === Simple Commands === | ||
* Sequence of optional variable assignments | * Sequence of optional variable assignments | ||
Line 68: | Line 68: | ||
* Returns its exit status or 128+n if terminated by signal n | * Returns its exit status or 128+n if terminated by signal n | ||
=== Piping - using | symbol | === Piping - using | symbol === | ||
Output of one command becomes the input of a second | Output of one command becomes the input of a second | ||
<br><br> | <br><br> | ||
Line 76: | Line 76: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Redirection - using > symbol | === Redirection - using > symbol === | ||
* Input and output of a command may be redirected before it is executed | * Input and output of a command may be redirected before it is executed | ||
* May be used to open and close files for the current shell execution environment | * May be used to open and close files for the current shell execution environment | ||
Line 91: | Line 91: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Redirection - using >> symbol | === Redirection - using >> symbol === | ||
Append to file | Append to file | ||
<br><br> | <br><br> | ||
Line 99: | Line 99: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Redirecting Input - using < symbol | === Redirecting Input - using < symbol === | ||
'''command < file''' | '''command < file''' | ||
<br><br> | <br><br> | ||
Line 109: | Line 109: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Redirecting Errors | === Redirecting Errors === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cd /var/spool/ | cd /var/spool/ | ||
Line 118: | Line 118: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Using /dev/null | === Using /dev/null === | ||
We just want a command to execute, no matter what output or errors it gives | We just want a command to execute, no matter what output or errors it gives | ||
<br><br> | <br><br> | ||
Line 125: | Line 125: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Foreground Jobs | === Foreground Jobs === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
vi body.txt | vi body.txt | ||
Line 131: | Line 131: | ||
fg | fg | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Background Jobs - & | === Background Jobs - & === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
g /var/tmp/spooll1 & | g /var/tmp/spooll1 & | ||
jobs | jobs | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Stopping Jobs - kill | === Stopping Jobs - kill === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
ps a | ps a | ||
Line 142: | Line 142: | ||
jobs | jobs | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Special Files - . and .. | === Special Files - . and .. === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
ls -la . | ls -la . | ||
ls -la .. | ls -la .. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== The Command Prompt - PS1 | === The Command Prompt - PS1 === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
less ~/.bashrc | less ~/.bashrc | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Creating Aliases | === Creating Aliases === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cd | cd | ||
Line 160: | Line 160: | ||
echo "alias mnia='ls -laR > /var/tmp/testsearch'" >> .bash_aliases | echo "alias mnia='ls -laR > /var/tmp/testsearch'" >> .bash_aliases | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Using Aliases | === Using Aliases === | ||
Useful | Useful | ||
* for specifying the default version of a command that exists in several versions on your system | * for specifying the default version of a command that exists in several versions on your system | ||
Line 182: | Line 182: | ||
--> | --> | ||
=== Command history | === Command history === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
history | history | ||
Line 191: | Line 191: | ||
<CTRL+R> | <CTRL+R> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Command Line Edit - using Arrow Keys | === Command Line Edit - using Arrow Keys === | ||
UP and DOWN arrow keys allow to search through history of typed commands | UP and DOWN arrow keys allow to search through history of typed commands | ||
=== Command Line Edit - using vi | === Command Line Edit - using vi === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
vim mniam.txt | vim mniam.txt | ||
Line 207: | Line 207: | ||
vim-adventures.com | vim-adventures.com | ||
=== Customizing the Shell | === Customizing the Shell === | ||
* Startup files: | * Startup files: | ||
** /etc/profile | ** /etc/profile | ||
Line 226: | Line 226: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== The Home Directory - HOME | === The Home Directory - HOME === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
echo $HOME | echo $HOME | ||
Line 233: | Line 233: | ||
cat /etc/passwd | cat /etc/passwd | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== The Working Directory - pwd | === The Working Directory - pwd === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
pwd | pwd | ||
Line 242: | Line 242: | ||
echo $PWD | echo $PWD | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Changing Directories - cd | === Changing Directories - cd === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cd | cd | ||
Line 249: | Line 249: | ||
cd -LPe@ | cd -LPe@ | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Make Directory - mkdir | === Make Directory - mkdir === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
mkdir -v 1 2 3 | mkdir -v 1 2 3 | ||
Line 257: | Line 257: | ||
mkdir -m a=rwx jimmy | mkdir -m a=rwx jimmy | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Remove Directory - rmdir | === Remove Directory - rmdir === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
rmdir -v 2 | rmdir -v 2 | ||
rmdir -p 3/3a/3aa | rmdir -p 3/3a/3aa | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Interactive Copy - cp -i | === Interactive Copy - cp -i === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cp mniam 1 | cp mniam 1 | ||
cp -i mniam 1 | cp -i mniam 1 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Interactive Move - mv -i | === Interactive Move - mv -i === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
mv mniam 1/mniam | mv mniam 1/mniam | ||
Line 273: | Line 273: | ||
mv -i mniam 1/mniam | mv -i mniam 1/mniam | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Interactive Remove - rm -i | === Interactive Remove - rm -i === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
rm -i 1/mniam | rm -i 1/mniam | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Removing Directories - rm -r | === Removing Directories - rm -r === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
rm -r 3 | rm -r 3 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Wild Cards - File Name Generation | === Wild Cards - File Name Generation === | ||
?, *, ^, [], [-], {} | ?, *, ^, [], [-], {} | ||
<br><br> | <br><br> | ||
Line 293: | Line 293: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Word count - wc | === Word count - wc === | ||
Print the number of bytes, words and lines in files | Print the number of bytes, words and lines in files | ||
<br><br> | <br><br> | ||
Line 306: | Line 306: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Finding Files - find | === Finding Files - find === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
find / -name passwd | find / -name passwd | ||
Line 315: | Line 315: | ||
find . -type d | find . -type d | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Finding Text in Files - grep, sort, cut, uniq, tr | === Finding Text in Files - grep, sort, cut, uniq, tr === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cat /etc/passwd | grep -v -c root | cat /etc/passwd | grep -v -c root | ||
Line 327: | Line 327: | ||
* [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 10b (from point 13)]] | * [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 10b (from point 13)]] | ||
==== Quiz | ==== Quiz ==== | ||
What will be the result? First try to guess without testing commands | What will be the result? First try to guess without testing commands | ||
<br><br> | <br><br> | ||
Line 343: | Line 343: | ||
--> | --> | ||
=== Changing Permissions - chmod | === Changing Permissions - chmod === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
chmod a+rwx header.txt | chmod a+rwx header.txt | ||
Line 350: | Line 350: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Shell Programming | == Shell Programming == | ||
=== Creating Shell Scripts | === Creating Shell Scripts === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cd | cd | ||
Line 362: | Line 362: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Testing the Command | === Testing the Command === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cd | cd | ||
Line 370: | Line 370: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Creating the Script File | === Creating the Script File === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cd ~/myAwesomeScrs | cd ~/myAwesomeScrs | ||
Line 377: | Line 377: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Adding Execute Permissions | === Adding Execute Permissions === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cd ~/myAwesomeScrs | cd ~/myAwesomeScrs | ||
Line 385: | Line 385: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Testing the Script | === Testing the Script === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cd ~/myAwesomeScrs | cd ~/myAwesomeScrs | ||
Line 391: | Line 391: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Running the Script - time | === Running the Script - time === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
time ./scrFile2.sh | time ./scrFile2.sh | ||
Line 401: | Line 401: | ||
* [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 10c (from point 13)]] | * [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 10c (from point 13)]] | ||
=== Running the Script - dot | === Running the Script - dot === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
./scrFile2.sh | ./scrFile2.sh | ||
Line 408: | Line 408: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Running the Script - exec | === Running the Script - exec === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
exec ./scrFile2.sh | exec ./scrFile2.sh | ||
Line 418: | Line 418: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Running the Script - ksh | === Running the Script - ksh === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
ksh | ksh | ||
Line 426: | Line 426: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Debugging the Script | === Debugging the Script === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
cd ~/myAwesomeScrs | cd ~/myAwesomeScrs | ||
Line 454: | Line 454: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Exercise | === Exercise === | ||
* [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 2 (from Point 13)]] | * [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 2 (from Point 13)]] | ||
=== Passing Parameters | === Passing Parameters === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
./generator | ./generator | ||
Line 464: | Line 464: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== The read Command | === The read Command === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
read var | read var | ||
Line 472: | Line 472: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Using read in Scripts | === Using read in Scripts === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
echo -e "Give me fever: \n" | echo -e "Give me fever: \n" | ||
Line 481: | Line 481: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Choosing the Shell | === Choosing the Shell === | ||
[https://tldp.org/LDP/Bash-Beginners-Guide/html/Bash-Beginners-Guide.html#AEN7369 Comparison of shells] | [https://tldp.org/LDP/Bash-Beginners-Guide/html/Bash-Beginners-Guide.html#AEN7369 Comparison of shells] | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 496: | Line 496: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Tidying The Output | === Tidying The Output === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
# scrFile4.sh | # scrFile4.sh | ||
Line 528: | Line 528: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Tidying The Output Con't | === Tidying The Output Con't === | ||
* Colors | * Colors | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 542: | Line 542: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Suppressing Input - stty | === Suppressing Input - stty === | ||
* Manages baud rate, line discipline, deviations | * Manages baud rate, line discipline, deviations | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 554: | Line 554: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Special Characters and Variables | == Special Characters and Variables == | ||
* Quoted Strings - '''"''', ''''''' | * Quoted Strings - '''"''', ''''''' | ||
* Escape Character - '''\''' | * Escape Character - '''\''' | ||
Line 563: | Line 563: | ||
* Other Special Variables | * Other Special Variables | ||
=== Quotation Marks | === Quotation Marks === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
# scrFile6.sh | # scrFile6.sh | ||
Line 580: | Line 580: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Escape Character - \ | === Escape Character - \ === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
echo "This will print | echo "This will print | ||
Line 592: | Line 592: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Quoted Strings - ` | === Quoted Strings - ` === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 618: | Line 618: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Using $(...) | === Using $(...) === | ||
* Save the result to a variable | * Save the result to a variable | ||
** Command substitution | ** Command substitution | ||
Line 630: | Line 630: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== System Variables - set | === System Variables - set === | ||
* The '''set''' command enables options within a script. | * The '''set''' command enables options within a script. | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 646: | Line 646: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Variable with a null value | ==== Variable with a null value ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 655: | Line 655: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== User Variables - unset | === User Variables - unset === | ||
* Destruction of variables<syntaxhighlight lang="bash" inline> | * Destruction of variables <syntaxhighlight lang="bash" inline>unset p1 p2 p2</syntaxhighlight> | ||
unset p1 p2 p2 | |||
</syntaxhighlight> | |||
* Example | * Example | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 668: | Line 666: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Variables in Scripts | === Variables in Scripts === | ||
* Positional parameters ($0, $#, $1, $2, $3 ...) | * Positional parameters ($0, $#, $1, $2, $3 ...) | ||
** Arguments passed to the script from the command line [1] : $0, $1, $2, $3 . . . | ** Arguments passed to the script from the command line [1] : $0, $1, $2, $3 . . . | ||
Line 701: | Line 699: | ||
* [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 3]] | * [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 3]] | ||
=== Other Special Variables | === Other Special Variables === | ||
* '''$@''' and '''$*''' | * '''$@''' and '''$*''' | ||
** Denote all the positional parameters. | ** Denote all the positional parameters. | ||
Line 712: | Line 710: | ||
echo $? | echo $? | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Other Special Variables Example | ==== Other Special Variables Example ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 732: | Line 730: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<!-- TODO | <!-- TODO | ||
=== Typeset Command | === Typeset Command === | ||
=== Integer Variables | === Integer Variables === | ||
=== Special Constructs | === Special Constructs === | ||
--> | --> | ||
== Selection | == Selection == | ||
Conditional statements | Conditional statements | ||
* The if / then / else | * The if / then / else | ||
Line 748: | Line 746: | ||
* '''case''' statement | * '''case''' statement | ||
=== The if / then | === The if / then === | ||
* Weird syntax | * Weird syntax | ||
** fi statement | ** fi statement | ||
Line 762: | Line 760: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== The if / then / else | === The if / then / else === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
if [ condition-true ] | if [ condition-true ] | ||
Line 776: | Line 774: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== One liner if,then | === One liner if,then === | ||
* Keywords (or commands) begin statements | * Keywords (or commands) begin statements | ||
* Before a new statement on the same line begins, the old one must terminate | * Before a new statement on the same line begins, the old one must terminate | ||
Line 783: | Line 781: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== What is truth | === What is truth === | ||
* One of the biggest easter eggs in the shell | * One of the biggest easter eggs in the shell | ||
* '''Zero''' means ok, everything else is not | * '''Zero''' means ok, everything else is not | ||
Line 795: | Line 793: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Nesting if statements | === Nesting if statements === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
a=3 | a=3 | ||
Line 815: | Line 813: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Quoting variables being tested | === Quoting variables being tested === | ||
* A Good Practice | * A Good Practice | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 827: | Line 825: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Exercise | === Exercise === | ||
* [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 4]] | * [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 4]] | ||
=== and list (1) | === and list (1) === | ||
* A group of '''and''' operators | * A group of '''and''' operators | ||
* Sort of net, with piped logic | * Sort of net, with piped logic | ||
Line 849: | Line 847: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== and list (2) | === and list (2) === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 863: | Line 861: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== or list (1) | === or list (1) === | ||
* A group of '''or''' operators | * A group of '''or''' operators | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 901: | Line 899: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== The if / elif | === The if / elif === | ||
* Multiple conditions | * Multiple conditions | ||
* Good for '''different facts''' | * Good for '''different facts''' | ||
Line 920: | Line 918: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== case statement | === case statement === | ||
* Multiple conditions | * Multiple conditions | ||
* Good for '''same fact with different values''' | * Good for '''same fact with different values''' | ||
Line 957: | Line 955: | ||
* [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 5]] | * [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 5]] | ||
=== Operators | === Operators === | ||
* No floating point arithmetic | * No floating point arithmetic | ||
* Operators '''and''', '''or''' (&&, ||) | * Operators '''and''', '''or''' (&&, ||) | ||
* '''test''' command | * '''test''' command | ||
==== No floating point arithmetic | ==== No floating point arithmetic ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 971: | Line 969: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Operators and, or (&&, | |) | ==== Operators and, or (&&, | |) ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
if [ $condition1 ] && [ $condition2 ] | if [ $condition1 ] && [ $condition2 ] | ||
Line 984: | Line 982: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== test command | ==== test command ==== | ||
* An alternative for square brackets | * An alternative for square brackets | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 1,006: | Line 1,004: | ||
<!-- TODO improve this section, make it pretty | <!-- TODO improve this section, make it pretty | ||
=== Conditional Testing | === Conditional Testing === | ||
=== Testing File Attributes | === Testing File Attributes === | ||
=== Testing File Permissions | === Testing File Permissions === | ||
=== Multiple Tests - Nested ifs | === Multiple Tests - Nested ifs === | ||
=== Multiple Tests - elsif | === Multiple Tests - elsif === | ||
=== The NOT Condition | === The NOT Condition === | ||
=== Multiple Conditions in One Test | === Multiple Conditions in One Test === | ||
=== Testing Strings | === Testing Strings === | ||
=== Using Square Brackets | === Using Square Brackets === | ||
=== Avoiding Null Input | === Avoiding Null Input === | ||
=== Testing Numbers | === Testing Numbers === | ||
=== More on case | === More on case === | ||
=== Displaying Variables | === Displaying Variables === | ||
=== Placing Spaces | === Placing Spaces === | ||
=== Testing Commands | === Testing Commands === | ||
--> | --> | ||
== Iteration, Looping | == Iteration, Looping == | ||
* Iteration - '''while, until''' | * Iteration - '''while, until''' | ||
* Infinite Loop | * Infinite Loop | ||
* Iteration - '''for''' | * Iteration - '''for''' | ||
=== The loop for / in | === The loop for / in === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
for arg in [list] | for arg in [list] | ||
Line 1,036: | Line 1,034: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== for loop - 1 | === for loop - 1 === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
for arg in "$var1" "$var2" "$var3" ... "$varN" | for arg in "$var1" "$var2" "$var3" ... "$varN" | ||
Line 1,048: | Line 1,046: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== for - 2 | ==== for - 2 ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
for arg in [list] ; do | for arg in [list] ; do | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== for - 3 | ==== for - 3 ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,064: | Line 1,062: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== for - 4 | ==== for - 4 ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,076: | Line 1,074: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== for - 5 | ==== for - 5 ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,089: | Line 1,087: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== for - 6 | ==== for - 6 ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,112: | Line 1,110: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== for - 7 | ==== for - 7 ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,130: | Line 1,128: | ||
* [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 11]] | * [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 11]] | ||
=== The command seq | === The command seq === | ||
* Gives a sequenced data | * Gives a sequenced data | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 1,139: | Line 1,137: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== The while loop | === The while loop === | ||
* Be careful | * Be careful | ||
** It might not execute your code at all if the condition is false | ** It might not execute your code at all if the condition is false | ||
Line 1,149: | Line 1,147: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Example 1 - Simple while loop | ==== Example 1 - Simple while loop ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,164: | Line 1,162: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Example 2 - Another while loop | ==== Example 2 - Another while loop ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,179: | Line 1,177: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Example 4 - C-style syntax in a while loop | ==== Example 4 - C-style syntax in a while loop ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,195: | Line 1,193: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Example 5 - call function in test condition | ==== Example 5 - call function in test condition ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
t=0 | t=0 | ||
Line 1,216: | Line 1,214: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Example 6 - reading file | ==== Example 6 - reading file ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,229: | Line 1,227: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Loop until | === Loop until === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
until [ condition-is-true ] | until [ condition-is-true ] | ||
Line 1,237: | Line 1,235: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Example 1 - until loop | ==== Example 1 - until loop ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,253: | Line 1,251: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Example 2 - C-style | ==== Example 2 - C-style ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,269: | Line 1,267: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Controlling the loop | === Controlling the loop === | ||
* Break | * Break | ||
* Continue | * Continue | ||
Line 1,321: | Line 1,319: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== More than 9 Parameters - shift | === More than 9 Parameters - shift === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
shift N | shift N | ||
Line 1,331: | Line 1,329: | ||
** by default N=1 | ** by default N=1 | ||
==== Manual shift example | ==== Manual shift example ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,345: | Line 1,343: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Creating Menus | == Creating Menus == | ||
* Interactive programs | * Interactive programs | ||
** User select | ** User select | ||
*** PSs | *** PSs | ||
=== User select | === User select === | ||
<br><br> | <br><br> | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 1,360: | Line 1,358: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== PS1-4 | ==== PS1-4 ==== | ||
<br><br> | <br><br> | ||
Line 1,377: | Line 1,375: | ||
<!-- TODO improve this part | <!-- TODO improve this part | ||
=== Conditions - case | === Conditions - case === | ||
=== Creating a Menu | === Creating a Menu === | ||
=== Iteration - while, until | === Iteration - while, until === | ||
=== Holding the Output - sleep | === Holding the Output - sleep === | ||
=== Holding the Output - dummy read | === Holding the Output - dummy read === | ||
=== Ending the Script | === Ending the Script === | ||
=== Ending the Loop | === Ending the Loop === | ||
=== Hidden Option - forking a shell | === Hidden Option - forking a shell === | ||
=== Trapping Interrupts - trap | === Trapping Interrupts - trap === | ||
=== More on Interrupts | === More on Interrupts === | ||
=== Highlighting Text- tput | === Highlighting Text- tput === | ||
=== Positioning the Cursor - backtab \b | === Positioning the Cursor - backtab \b === | ||
=== Korn Shell Menu | === Korn Shell Menu === | ||
--> | --> | ||
== Sub-scripts and Functions | == Sub-scripts and Functions == | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
function function_name { | function function_name { | ||
Line 1,409: | Line 1,407: | ||
** <small>https://w1.fi/wpa_supplicant/</small> | ** <small>https://w1.fi/wpa_supplicant/</small> | ||
=== Functions Con't | === Functions Con't === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
updateMeViaFunc='' | updateMeViaFunc='' | ||
Line 1,427: | Line 1,425: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Sub-scripts | === Sub-scripts === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
source scriptname.sh | source scriptname.sh | ||
Line 1,437: | Line 1,435: | ||
<!-- TODO improve this part | <!-- TODO improve this part | ||
=== Local and Global Variables | === Local and Global Variables === | ||
=== Sub-scripts | === Sub-scripts === | ||
=== Export Command | === Export Command === | ||
=== Exit Status | === Exit Status === | ||
=== Aliases | === Aliases === | ||
=== Functions | === Functions === | ||
=== Useful Functions | === Useful Functions === | ||
=== Return Status | === Return Status === | ||
=== Manipulating Functions | === Manipulating Functions === | ||
=== Functions in Scripts | === Functions in Scripts === | ||
--> | --> | ||
== Advanced Commands | == Advanced Commands == | ||
* Test operators | * Test operators | ||
* Operators | * Operators | ||
* Comparison operators | * Comparison operators | ||
=== Test file | === Test file === | ||
* '''-e''' ''exists'' ( file or directory both true ) | * '''-e''' ''exists'' ( file or directory both true ) | ||
* '''-s''' ''file not zero size'' | * '''-s''' ''file not zero size'' | ||
=== Test the file type | === Test the file type === | ||
* '''-f''' ''regular file ( not directory, or device file)'' | * '''-f''' ''regular file ( not directory, or device file)'' | ||
* '''-d''' ''is directory'' | * '''-d''' ''is directory'' | ||
=== Test file attributes | === Test file attributes === | ||
* '''-r''' ''file has read permission (for the user running the test)'' | * '''-r''' ''file has read permission (for the user running the test)'' | ||
Line 1,470: | Line 1,468: | ||
* '''-x''' ''file has execute permission (for the user running the test)'' | * '''-x''' ''file has execute permission (for the user running the test)'' | ||
=== The assignment operator | === The assignment operator === | ||
<br><br> | <br><br> | ||
Line 1,479: | Line 1,477: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Arithmetic operators | === Arithmetic operators === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
let "z=5**3" # 5 * 5 * 5 | let "z=5**3" # 5 * 5 * 5 | ||
Line 1,492: | Line 1,490: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== Arithmetic Expansion | ==== Arithmetic Expansion ==== | ||
Translating a string into a numerical expression | Translating a string into a numerical expression | ||
Line 1,505: | Line 1,503: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Operators operations on bits (bitwise operators) | === Operators operations on bits (bitwise operators) === | ||
<br><br> | <br><br> | ||
Line 1,523: | Line 1,521: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Logical operators | === Logical operators === | ||
<br><br> | <br><br> | ||
Line 1,546: | Line 1,544: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Numeric constants | === Numeric constants === | ||
<br><br> | <br><br> | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 1,565: | Line 1,563: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Comparing arithmetic using the command if | === Comparing arithmetic using the command if === | ||
<br><br> | <br><br> | ||
Line 1,576: | Line 1,574: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Integer comparison operators | === Integer comparison operators === | ||
<br><br> | <br><br> | ||
Line 1,592: | Line 1,590: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Comparing strings | === Comparing strings === | ||
'''Always quote a tested string.''' | '''Always quote a tested string.''' | ||
Line 1,604: | Line 1,602: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Comparing the complex (and, or) | === Comparing the complex (and, or) === | ||
<br><br> | <br><br> | ||
Line 1,617: | Line 1,615: | ||
<!-- TODO improve that part | <!-- TODO improve that part | ||
=== Debugging - set | === Debugging - set === | ||
=== Setting - set | === Setting - set === | ||
=== Merging Files - join | === Merging Files - join === | ||
=== Merging Files - paste, basename and dirname | === Merging Files - paste, basename and dirname === | ||
=== Job Control - jobs | === Job Control - jobs === | ||
--> | --> | ||
=== Regular Expressions | === Regular Expressions === | ||
* Commonly used in scripts, such as grep, sed and awk. | * Commonly used in scripts, such as grep, sed and awk. | ||
** As of version 3, Bash has acquired its own RE-match operator: =~. | ** As of version 3, Bash has acquired its own RE-match operator: =~. | ||
==== Know RE | ==== Know RE ==== | ||
* A character set | * A character set | ||
* An anchor - ^, $ | * An anchor - ^, $ | ||
* Modifiers - *, (), \, [] | * Modifiers - *, (), \, [] | ||
==== *,.,^,$ | ==== *,.,^,$ ==== | ||
* "1133*" : 113, 1133, 1133333... | * "1133*" : 113, 1133, 1133333... | ||
==== . | ==== . ==== | ||
* "13." : 1133, 11333 | * "13." : 1133, 11333 | ||
==== *,.,^,$ | ==== *,.,^,$ ==== | ||
* "^" : line start | * "^" : line start | ||
==== ^,$ | ==== ^,$ ==== | ||
* "$" : line end "XXX$" | * "$" : line end "XXX$" | ||
* "^$": empty line | * "^$": empty line | ||
==== [...] | ==== [...] ==== | ||
* "[xyz]" | * "[xyz]" | ||
Line 1,660: | Line 1,658: | ||
* "[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]" : NNN-NN-NNNN | * "[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]" : NNN-NN-NNNN | ||
==== \ | ==== \ ==== | ||
* "\$" | * "\$" | ||
* "\\" | * "\\" | ||
==== \<\> | ==== \<\> ==== | ||
'''word boundary''' | '''word boundary''' | ||
Line 1,672: | Line 1,670: | ||
=== Extended RE + | === Extended RE + === | ||
==== + | ==== + ==== | ||
'''"+" matches one or more of previous RE''' | '''"+" matches one or more of previous RE''' | ||
Line 1,683: | Line 1,681: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== \{\} | ==== \{\} ==== | ||
'''number of occurrences''' | '''number of occurrences''' | ||
Line 1,698: | Line 1,696: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== (),| | ==== (),| ==== | ||
* () group REs | * () group REs | ||
Line 1,709: | Line 1,707: | ||
<!-- TODO imrpove this part | <!-- TODO imrpove this part | ||
=== Global Regular Expression Printer - grep | === Global Regular Expression Printer - grep === | ||
=== Expression grep - egrep | === Expression grep - egrep === | ||
=== Fast grep - fgrep | === Fast grep - fgrep === | ||
=== Computations - expr | === Computations - expr === | ||
=== Computations – bc, eval Command, | === Computations – bc, eval Command, === | ||
=== Argument Processing | === Argument Processing === | ||
--> | --> | ||
=== getopts Command | === getopts Command === | ||
* Parses command-line arguments passed to the script. | * Parses command-line arguments passed to the script. | ||
* It permits passing and concatenating multiple options and associated arguments to a script | * It permits passing and concatenating multiple options and associated arguments to a script | ||
Line 1,727: | Line 1,725: | ||
* External alternatives: getopt external command, getopt library function | * External alternatives: getopt external command, getopt library function | ||
=== getopts Command example | === getopts Command example === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
# Here we observe how 'getopts' processes command-line arguments to script. | # Here we observe how 'getopts' processes command-line arguments to script. | ||
Line 1,785: | Line 1,783: | ||
* [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 9]] | * [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 9]] | ||
=== Using Arrays | === Using Arrays === | ||
* Newer versions of Bash support one-dimensional arrays. | * Newer versions of Bash support one-dimensional arrays. | ||
Line 1,817: | Line 1,815: | ||
<!-- TODO improve this part | <!-- TODO improve this part | ||
=== Advanced Edit – vi & sed | === Advanced Edit – vi & sed === | ||
=== vi - Mapping Key Combinations | === vi - Mapping Key Combinations === | ||
=== Mapping Control Keys | === Mapping Control Keys === | ||
=== Using Abbreviations | === Using Abbreviations === | ||
=== Editing Many Files | === Editing Many Files === | ||
=== Regular Expressions | === Regular Expressions === | ||
=== Global Insert | === Global Insert === | ||
--> | --> | ||
=== Here document | === Here document === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
#!/bin/bash | #!/bin/bash | ||
Line 1,844: | Line 1,842: | ||
* [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 14]] | * [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 14]] | ||
=== Batch Stream EDitor - sed | === Batch Stream EDitor - sed === | ||
* Performs basic transformations on text read from a file or a pipe | * Performs basic transformations on text read from a file or a pipe | ||
* The result is sent to standard output | * The result is sent to standard output | ||
Line 1,865: | Line 1,863: | ||
</pre> | </pre> | ||
==== sed delete, /d | ==== sed delete, /d ==== | ||
<syntaxhighlight lang=bash> | <syntaxhighlight lang="bash"> | ||
cat -n example | cat -n example | ||
sed '/erors/d' example | sed '/erors/d' example | ||
Line 1,875: | Line 1,873: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== sed print, /p | ==== sed print, /p ==== | ||
<syntaxhighlight lang=bash> | <syntaxhighlight lang="bash"> | ||
sed '/erors/p' example | sed '/erors/p' example | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== sed suppress, -n | ==== sed suppress, -n ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
sed -n '/erors/p' example | sed -n '/erors/p' example | ||
sed -n '/a text/,/This/p' example | sed -n '/a text/,/This/p' example | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== sed file, -f | ==== sed file, -f ==== | ||
==== sed Multiple Input | ==== sed Multiple Input ==== | ||
==== sed Find and Replace | ==== sed Find and Replace ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
sed 's/erors/errors/' example | sed 's/erors/errors/' example | ||
Line 1,895: | Line 1,893: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== sed Examples | ==== sed Examples ==== | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
grep sed /etc/init.d/* | grep sed /etc/init.d/* | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Text File Processing - awk | == Text File Processing - awk == | ||
* Yet another popular stream editor | * Yet another popular stream editor | ||
Line 1,912: | Line 1,910: | ||
** Easy to read and write | ** Easy to read and write | ||
=== The awk Programming Tool | === The awk Programming Tool === | ||
'''run awk = specify an awk program = tells awk what to do''' | '''run awk = specify an awk program = tells awk what to do''' | ||
Line 1,928: | Line 1,926: | ||
*** <syntaxhighlight lang="bash">awk -f PROGRAM-FILE inputfile(s)</syntaxhighlight> | *** <syntaxhighlight lang="bash">awk -f PROGRAM-FILE inputfile(s)</syntaxhighlight> | ||
=== Pattern Matching | === Pattern Matching === | ||
* The condition may be: | * The condition may be: | ||
** a regular expression | ** a regular expression | ||
Line 1,940: | Line 1,938: | ||
** END action is performed after all the lines have been read or another action executes an exit statement | ** END action is performed after all the lines have been read or another action executes an exit statement | ||
* If there is no condition(can be missing/omitted), the action is applied to all lines | * If there is no condition(can be missing/omitted), the action is applied to all lines | ||
=== Processing input | === Processing input === | ||
* Each line is split into fields based on the contents of the variable FS | * Each line is split into fields based on the contents of the variable FS | ||
** FS by default is any whitespace | ** FS by default is any whitespace | ||
Line 1,948: | Line 1,946: | ||
<!-- TODO improve this part | <!-- TODO improve this part | ||
=== Regular Expressions | === Regular Expressions === | ||
=== Comparison Patterns | === Comparison Patterns === | ||
=== Compound Patterns | === Compound Patterns === | ||
--> | --> | ||
=== Range Patterns | === Range Patterns === | ||
NR == 10, NR == 20 (NR - current line number) | NR == 10, NR == 20 (NR - current line number) | ||
<!-- TODO improve this part | <!-- TODO improve this part | ||
=== Special Patterns | === Special Patterns === | ||
=== Built-in Functions | === Built-in Functions === | ||
=== Troubleshooting awk Scripts | === Troubleshooting awk Scripts === | ||
=== Passing Parameters | === Passing Parameters === | ||
=== Using Contains | === Using Contains === | ||
=== printf Function | === printf Function === | ||
=== Computations | === Computations === | ||
=== Functions | === Functions === | ||
=== substr | === substr === | ||
=== length | === length === | ||
--> | --> | ||
=== Action Statements | === Action Statements === | ||
* Can be any computation task: | * Can be any computation task: | ||
** modify the input line | ** modify the input line | ||
Line 1,980: | Line 1,978: | ||
<!-- TODO improve it | <!-- TODO improve it | ||
=== Control Flow Statements | === Control Flow Statements === | ||
=== Arrays | === Arrays === | ||
=== Arrays with for Loops | === Arrays with for Loops === | ||
--> | --> | ||
=== awk Examples | === awk Examples === | ||
==== awk example 1 | ==== awk example 1 ==== | ||
'print' command | 'print' command | ||
<syntaxhighlight lang="bash">df -h | awk '{ print $2 " " $4 }'</syntaxhighlight> | <syntaxhighlight lang="bash">df -h | awk '{ print $2 " " $4 }'</syntaxhighlight> | ||
Line 1,993: | Line 1,991: | ||
* [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 15]] | * [[UNIX/Linux_Shell_Scripting#Exercises_.E2.8C.98|Exercise nr 15]] | ||
== References | == References == | ||
[http://www.tldp.org/LDP/Bash-Beginners-Guide/html/Bash-Beginners-Guide.html#sect_01_03 Executing Commands] | [http://www.tldp.org/LDP/Bash-Beginners-Guide/html/Bash-Beginners-Guide.html#sect_01_03 Executing Commands] | ||
Line 2,009: | Line 2,007: | ||
[https://tldp.org/LDP/abs/html/abs-guide.html#SAMPLE-BASHRC Sample .bashrc] | [https://tldp.org/LDP/abs/html/abs-guide.html#SAMPLE-BASHRC Sample .bashrc] | ||
== Exercises | == Exercises == | ||
<pre> | <pre> | ||
0. Install 'git' and create new repository in '~/Documents/scripts' folder. | 0. Install 'git' and create new repository in '~/Documents/scripts' folder. |
Latest revision as of 16:34, 29 August 2025
- title
- UNIX/Linux Shell Scripting
- author
- Lukasz Sokolowski (NobleProg Ltd)
UNIX/Linux Shell Scripting
UNIX/Linux Shell Scripting Training Materials
Copyright Notice
Copyright © 2004-2025 by NobleProg Limited All rights reserved.
This publication is protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying, recording, or likewise.
THIS IS A DRAFT
This text may not be complete.
Review of Basics - optional
Files
touch filo.txt
echo first line > filo1.txt
Directories and Processes
mkdir diro
ps aux
ps -C chrome
top
Displaying Directories - ls
ls -la
ls -s
ls -d
ls -h
ls -S
Getting Help - man, info
--help
help ls
man ls
man man
man 8 useradd
man 5 passwd
info ls
info coreutils 'tac invocation'
Displaying Files - cat, more
cat filo.txt
more filo1.txt
less filo.txt
tac filo
less internal options h, /, ?
Simple Commands
- Sequence of optional variable assignments
- Fol‐lowed by blank-separated words and redirections
- Terminated by a control operator
- First word is command to be executed (arg 0)
- Remaining words are arguments for invoked command
- Returns its exit status or 128+n if terminated by signal n
Piping - using | symbol
Output of one command becomes the input of a second
ls | grep Do
gunzip file.tar.gz | tar xvf -
Redirection - using > symbol
- Input and output of a command may be redirected before it is executed
- May be used to open and close files for the current shell execution environment
- File descriptors: stdin(0), stdout(1) and stderr(2)
ls -l /dev/std*
ls -l /proc/self/fd/[0-2]
date
at 1020
ls -l /proc/self/fd > /var/tmp/fdtest.at
<CTRL+D>
Redirection - using >> symbol
Append to file
date >> backup.log
echo backup succeeded >> backup.log
Redirecting Input - using < symbol
command < file
read p1 < header.txt
read p2 < body.txt
read p3 < footer.txt
echo $p1 $p2 $p3 >> hbf.txt
Redirecting Errors
cd /var/spool/
ls -l * 2> /var/tmp/unac-in-spool
ls -l * > /var/tmp/spool 2>&1
ls -l * 2>&1 > /var/tmp/spool1
ls -l * &> /var/tmp/spool2
Using /dev/null
We just want a command to execute, no matter what output or errors it gives
ls -l * &> /dev/null
Foreground Jobs
vi body.txt
<CTRL+Z> # stop process
fg
Background Jobs - &
g /var/tmp/spooll1 &
jobs
Stopping Jobs - kill
ps a
kill 8209
jobs
Special Files - . and ..
ls -la .
ls -la ..
The Command Prompt - PS1
less ~/.bashrc
Creating Aliases
cd
alias
alias mnia='ls -laR > /var/tmp/testsearch'
unalias mnia
echo "# My aliases" >> .bash_aliases
echo "alias mnia='ls -laR > /var/tmp/testsearch'" >> .bash_aliases
Using Aliases
Useful
- for specifying the default version of a command that exists in several versions on your system
- to specify default options to a command
- for correcting incorrect spelling
mnia
ll
Exercises
- Exercise nr 1 (from point 13)
- Reverse one by one character, use 'filo1.txt'
- Hack 'ls' command, it should result with 'sl' program instead (after playing go back to the usual 'ls')
Command history
history
!!
!4
history 10
less .bash_history
<CTRL+R>
Command Line Edit - using Arrow Keys
UP and DOWN arrow keys allow to search through history of typed commands
Command Line Edit - using vi
vim mniam.txt
:
<CTRL+R>
'%', '/', '.', ':'
history
www.openvim.com
vim-adventures.com
Customizing the Shell
- Startup files:
- /etc/profile
- /etc/bashrc (bash.bashrc)
- $HOME/.bash_profile (.bashrc)
- $HOME/.bash_logout, $HOME/.bash_history, $HOME/.bash_aliases
- /etc/passwd
- Environmental variables
- Commands:
shopt -s cdspell
shopt -u
export
set
help
env
The Home Directory - HOME
echo $HOME
cd
adduser
cat /etc/passwd
The Working Directory - pwd
pwd
env pwd
whereis pwd
/bin/pwd
help pwd
echo $PWD
Changing Directories - cd
cd
cd ..
cd ../../
cd -LPe@
Make Directory - mkdir
mkdir -v 1 2 3
mkdir 2
mkdir -p 3/3a/3aa
ls -la -R 3/
mkdir -m a=rwx jimmy
Remove Directory - rmdir
rmdir -v 2
rmdir -p 3/3a/3aa
Interactive Copy - cp -i
cp mniam 1
cp -i mniam 1
Interactive Move - mv -i
mv mniam 1/mniam
cp 1/mniam mniam
mv -i mniam 1/mniam
Interactive Remove - rm -i
rm -i 1/mniam
Removing Directories - rm -r
rm -r 3
Wild Cards - File Name Generation
?, *, ^, [], [-], {}
echo rm -R *
ls -l h??.txt
ls -l [hf]*
ls -l [b-h]*
ls -l [^hf]*
ls -l {b*,p*,*tuf*}
Word count - wc
Print the number of bytes, words and lines in files
wc -m header.txt
wc -l footer.txt
wc -L hbf.txt
wc -w header.txt footer.txt
wc -w -
umpa lumpa dumpa
<CTRL+D>
Finding Files - find
find / -name passwd
sudo find / -name passwd
find . -empty
find . -executable
find . -group drupalpro
find . -type d
Finding Text in Files - grep, sort, cut, uniq, tr
cat /etc/passwd | grep -v -c root
ls */* | sort -t / -k 1,1R -k 2,2
cut -f 2 -d " " header.txt
uniq -d header.txt
tr a-z A-Z
Exercise
Quiz
What will be the result? First try to guess without testing commands
df -h | grep -v File | awk '{ print $5 }' | cut -d "%" -f1 -
ls */* | sort -t / -k 1,1R -k 2,2
awk '{print length, $0}' /etc/passwd | sort -n | cut -f2- -d' '
Changing Permissions - chmod
chmod a+rwx header.txt
chmod 755 footer.txt
chown drupalpro:drupalpro hbf.txt
Shell Programming
Creating Shell Scripts
cd
mkdir myAwesomeScrs
cd myAwesomeScrs
touch myScr.sh
nano myScr.sh
# adding shabang -> #!/bin/bash
# printing to screen -> echo 'my first script'
Testing the Command
cd
cd myAwesomeScrs
myScr.sh
# shouldn't work yet, why?
Creating the Script File
cd ~/myAwesomeScrs
> scrFile.sh
echo '# This is a comment' > scrFile1.sh
Adding Execute Permissions
cd ~/myAwesomeScrs
echo '# this one will work' > scrFile2.sh
echo 'echo "works"' >> scrFile2.sh
chmod u+x scrFile2.sh
Testing the Script
cd ~/myAwesomeScrs
bash scrFile2.sh
Running the Script - time
time ./scrFile2.sh
time -p ./scrFile2.sh
help time
Exercise
Running the Script - dot
./scrFile2.sh
. scrFile2.sh
help .
Running the Script - exec
exec ./scrFile2.sh
# what the heck?! (-;
# open CLI again
bash
exec ./scrFile2.sh
help exec
Running the Script - ksh
ksh
apt install ksh
ksh scrFile2.sh
ksh --help
Debugging the Script
cd ~/myAwesomeScrs
echo '#!/bin/bash -x' > scrFile3.sh
echo '' >> scrFile3.sh
echo 'echo "this will be doubled"' >> scrFile3.sh
echo '' >> scrFile3.sh
echo 'date' >> scrFile3.sh
echo '' >> scrFile3.sh
echo 'echo "End of story"' >> scrFile3.sh
chmod u+x scrFile3.sh
./scrFile3.sh
Trap
#!/bin/bash
# traptest.sh
trap "echo Booh!" SIGINT SIGTERM # man 7 signal , kill -l
echo "pid is $$"
while : # This is the same as "while true".
do
sleep 60 # This script is not really doing anything.
done
Exercise
Passing Parameters
./generator
echo 'echo "First argument is: $1"' >> scr.sh
./scr.sh meow
The read Command
read var
echo $var
read var1 var2 var3
echo $var{1..3}
Using read in Scripts
echo -e "Give me fever: \n"
read fevervar
[ $fevervar ] && echo "You're so hot "$fevervar
[ ! $fevervar ] && echo "Don't cheat!" && exit 1
exit 0
Choosing the Shell
#!/bin/sh
### Bourne shell, simple and restricted, good for security reasons
#!/bin/csh
### C shell, supports internally a lot of C language
#!/bin/ksh
### Korn shell, backward-compatible with the Bourne shell and includes many features of the C shell
#!/bin/bash
### man bash, info bash
#!/bin/zsh
### https://www.zsh.org/
Tidying The Output
# scrFile4.sh
### With echo
echo -e "I have some tidy content in me.\nEach sentence is separated into the new line.\nAlso there is one tabulator here:\there I'am."
echo "Hey Mate. What is the biggest kangaroo in the world? Give me the proper answer: "
read kangaroo
echo -e "You gave the wrong one, sorry.. It's not the $kangaroo. It was Roger!"
### Readability
printf 'n\np\n3\n\n\n\n\nt\n3\n8e\nw' | fdisk /dev/sda
# with HERE docs
fdisk /dev/sda <<EOF
n
n
3
t
8e
w
EOF
### Exit codes
cd ~/myAwesomeScrs
touch scrFile999.sh ; [ -f "scrFile999.sh" ] && echo "You are focused and following the examples properly! Good job, nice one, Mate!" && exit 0
#rm scrFile999.sh ; [ ! -f "scrFile999.sh" ] && echo "You naughty boy! Come on, be a good one and follow the trainer's steps, right?" && exit 1
# Run this script and check the value of global var: '$?'
# Comment out the line 25. Uncomment the line 26, then run this script again and check '$?'
Tidying The Output Con't
- Colors
env | grep color
cat ~/.bashrc | grep color
- Parsing
# scrFile5.sh
echo '<div class="">Tidy.<div>' > mytags.html
apt install tidy -y
tidy mytags.html
Suppressing Input - stty
- Manages baud rate, line discipline, deviations
stty sane
stty -echo # echo
stty -a
- Examples
grep stty /etc/*/*
Special Characters and Variables
- Quoted Strings - "', ''
- Escape Character - \
- Quoted Strings - `
- System Variables
- User Variables
- Variables in Scripts
- Other Special Variables
Quotation Marks
# scrFile6.sh
a=375
hello=$a
echo "$hello" # 375
echo "${hello}" # 375
echo
hello="A B C D"
echo $hello # A B C D
echo "$hello" # A B C D
echo
echo '$hello' # $hello
Escape Character - \
echo "This will print
as two lines."
echo "This will print \
as one line."
p=20
echo "\$p = $p"
Quoted Strings - `
#!/bin/bash
a=23 # Simple case
echo $a
b=$a
echo $b
# Now, getting a little bit fancier (command substitution).
a=`echo Hello!` # Assigns result of 'echo' command to 'a' ...
echo $a
# Note that including an exclamation mark (!) within a
#+ command substitution construct will not work from the command-line,
#+ since this triggers the Bash "history mechanism."
# Inside a script, however, the history functions are disabled by default.
a=`ls -l` # Assigns result of 'ls -l' command to 'a'
echo $a # Unquoted, however, it removes tabs and newlines.
echo
echo "$a" # The quoted variable preserves whitespace.
exit 0
Using $(...)
- Save the result to a variable
- Command substitution
script_name=$(basename $0)
echo "The name of this script is $script_name."
# The $(...) form of command substitution treats a double backslash in a different way than `...`.
echo `echo "\\"`
echo $(echo "\\")
System Variables - set
- The set command enables options within a script.
#!/bin/bash
set -o verbose
# Echoes all commands before executing.
set -v
# Exact same effect as above.
set +v
# Command echoing off.
command
# Not echoed.
Variable with a null value
#!/bin/bash
echo "$uninitialized" # (blank line)
let "uninitialized += 5" # Add 5 to it.
echo "$uninitialized" # 5
User Variables - unset
- Destruction of variables
unset p1 p2 p2
- Example
#!/bin/bash
variable=hello
echo "variable = $variable"
unset variable
Variables in Scripts
- Positional parameters ($0, $#, $1, $2, $3 ...)
- Arguments passed to the script from the command line [1] : $0, $1, $2, $3 . . .
- $0 is the name of the script itself, $1 is the first argument, $2 the second, $3 the third, and so forth.
- After $9, the arguments must be enclosed in brackets, for example, ${10}, ${11}, ${12}
#!/bin/bash
# scriptname 1 2 3
MINPARAMS=3
echo "The number of parameters is \"$#\"."
echo "The name of this script is \"$0\"."
echo "The name of this script is \"`basename $0`\"."
echo
if [ -n "$1" ]
then
echo "Parameter #1 is $1"
fi
if [ -n "$2" ]
then
echo "Parameter #2 is $2"
fi
if [ -n "$3" ]
then
echo "Parameter #3 is $3"
fi
Exercise
Other Special Variables
- $@ and $*
- Denote all the positional parameters.
- $#
- Number of params passed to the script
- $?
- Use the status of completion of the program in a script
# return last command status code
echo $?
Other Special Variables Example
#!/bin/bash
# Try multiple parameters with white spaces as well
for vars in $*
do
echo "Looping \$*, \$vars is:"
echo $vars
done
for vars in $@
do
echo "Looping \$*, \$vars is:"
echo $vars
done
exit 0
Selection
Conditional statements
- The if / then / else
- One liner if,then
- Nesting if statements
- The if / elif
- What is truth
- Quoting variables being tested
- and vs or lists
- case statement
The if / then
- Weird syntax
- fi statement
- no curlies {}
- Fragile with empty spaces ([condition-true ])
if [ condition-true ]
then
command 1
command 2
...
fi
The if / then / else
if [ condition-true ]
then
command 1
command 2
...
else
command 3
command 4
...
fi
One liner if,then
- Keywords (or commands) begin statements
- Before a new statement on the same line begins, the old one must terminate
if [ -x "$filename" ]; then ...
What is truth
- One of the biggest easter eggs in the shell
- Zero means ok, everything else is not
if [ 0 ] # zero
then
echo "0 is true."
else # Or else ...
echo "0 is false."
fi # 0 is true.
Nesting if statements
a=3
if [ "$a" -gt 0 ]
then
if [ "$a" -lt 5 ]
then
echo "The value of \"a\" lies somewhere between 0 and 5."
fi
fi
# Same result as:
if [ "$a" -gt 0 ] && [ "$a" -lt 5 ]
then
echo "The value of \"a\" lies somewhere between 0 and 5."
fi
Quoting variables being tested
- A Good Practice
#!/bin/bash
# if-3.sh
if [[ -z "$1" ]]
then
echo "Need one argument!"
fi
Exercise
and list (1)
- A group of and operators
- Sort of net, with piped logic
#!/bin/bash
# if-4.sh
# command-1 && command-2 && command-3 && ... command-n
if [ ! -z "$1" ] && echo "Argument #1 = $1" && [ ! -z "$2" ] && \
echo "Argument #2 = "$2""
then
echo "2 arguments passed to script."
else
echo "Fewer than 2 arguments passed to script."
fi
exit $?
and list (2)
#!/bin/bash
# if-5.sh
ARGS=1
E_BADARGS=85
[[ $# -ne "$ARGS" ]] && echo "Usage: $(basename $0) "$ARGS" argument(s)" && exit "$E_BADARGS"
echo "Correct number of arguments passed to this script."
exit 0
or list (1)
- A group of or operators
#!/bin/bash
# if-7.sh
# command-1 || command-2 || command-3 || ... command-n
E_BADARGS=85
[[ -z "$1" ]] && echo "Usage: `basename $0` filename" && exit $E_BADARGS
file=$1
[ ! -f "$file" ] && echo "File \"$file\" not found. Refusing to delete a nonexistent file."
[ ! -f "$file" ] || (rm -f $file; echo "File \"$file\" deleted.")
exit $?
or list (2)
# /etc/rc.d/init.d/single
[ -x /usr/bin/clear ] && /usr/bin/clear
for i in /etc/rc1.d/S[0-9][0-9]* ; do
[ -x "$i" ] || continue
# Reject backup files and files generated by rpm.
case "$1" in
*.rpmsave|*.rpmorig|*.rpmnew|*~|*.orig)
continue;;
esac
[ "$i" = "/etc/rc1.d/S00single" ] && continue
# ==> Set script name, but don't execute it yet.
$i start
done
The if / elif
- Multiple conditions
- Good for different facts
if [ condition1 ]
then
command1
command2
command3
elif [ condition2 ]
# Same as else if
then
command4
command5
else
default-command
fi
case statement
- Multiple conditions
- Good for same fact with different values
- Really weird syntax - *), esac
case "$variable" in
"$condition1" )
command...
;;
"$condition2" )
command...
;;
esac
case
#!/bin/bash
case $( arch ) in # $( arch ) returns machine architecture.
# Equivalent to 'uname -m' ...
i386 ) echo "80386-based machine";;
i486 ) echo "80486-based machine";;
i586 ) echo "Pentium-based machine";;
i686 ) echo "Pentium2+-based machine";;
* ) echo "Other type of machine";;
esac
exit 0
Exercise
Operators
- No floating point arithmetic
- Operators and, or (&&, ||)
- test command
No floating point arithmetic
a=1.5
let "b = $a + 1.3" # Error.
Operators and, or (&&, | |)
if [ $condition1 ] && [ $condition2 ]
# Same as: if [ $condition1 -a $condition2 ]
if [[ $condition1 && $condition2 ]]
if [ $condition1 ] || [ $condition2 ]
# Same as: if [ $condition1 -o $condition2 ]
if [[ $condition1 || $condition2 ]]
test command
- An alternative for square brackets
if test -x $file
then
...
if [[ -x $file ]]
then
...
bash$ whereis [
: /usr/bin/[ /usr/share/man/man1/[.1.gz
bash$ type test
test is a shell builtin <---- no need to call /usr/bin/test
bash$ info test
Iteration, Looping
- Iteration - while, until
- Infinite Loop
- Iteration - for
The loop for / in
for arg in [list]
do
command(s)...
done
for loop - 1
for arg in "$var1" "$var2" "$var3" ... "$varN"
# In pass 1 of the loop, arg = $var1
# In pass 2 of the loop, arg = $var2
# In pass 3 of the loop, arg = $var3
# ...
# In pass N of the loop, arg = $varN
# Arguments in [list] quoted to prevent possible word splitting.
for - 2
for arg in [list] ; do
for - 3
#!/bin/bash
for planet in Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto
do
echo $planet # Each planet on a separate line.
done
for - 4
#!/bin/bash
for planet in "Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto"
do
echo $planet
done
exit 0
for - 5
#!/bin/bash
for planet in "Mercury 36" "Venus 67" "Earth 93" "Mars 142" "Jupiter 483"
do
set -- $planet
echo "$1 $2,000,000 miles from the sun"
done
exit 0
for - 6
#!/bin/bash
FILES="/usr/sbin/accept
/usr/bin/fakefile
/sbin/ypbind"
for file in $FILES
do
if [ ! -e "$file" ]
then
echo "$file does not exist."; echo
continue
fi
ls -l $file | awk '{ print $8 " file size: " $5 }' # Print 2 fields.
whatis `basename $file` # File info.
echo
done
exit 0
for - 7
#!/bin/bash
filename="*txt"
for file in $filename
do
echo "Contents of $file"
echo "---"
cat "$file"
echo
done
Exercise
The command seq
- Gives a sequenced data
seq 5
seq 5 10
seq 5 2 9
seq -s ,5
The while loop
- Be careful
- It might not execute your code at all if the condition is false
while [ condition ]
do
command(s)...
done
Example 1 - Simple while loop
#!/bin/bash
var0=0
LIMIT=10
while [ "$var0" -lt "$LIMIT" ].
do
echo -n "$var0 "
let "var0 += 1"
done
Example 2 - Another while loop
#!/bin/bash
while [ "$var1" != "end" ]
do
echo "Input variable #1 (end to exit) "
read var1
echo "variable #1 = $var1"
echo
done
exit 0
Example 4 - C-style syntax in a while loop
#!/bin/bash
# while-4.sh
LIMIT=10
((a = 1))
while (( a <= LIMIT ))
do
echo -n "$a "
((a += 1))
done
Example 5 - call function in test condition
t=0
condition ()
{
((t++))
if [ $t -lt 5 ]
then
return 0 # true
else
return 1 # false
fi
}
while condition
do
echo "Still going: t = $t"
done
Example 6 - reading file
#!/bin/bash
[ $# -lt 1 ] && echo "Usage: `basename $0` filename" && exit || filename=$1
cat $filename | # Supply input from a file.
while read line # As long as there is another line to read ...
do
echo $line
done
Loop until
until [ condition-is-true ]
do
command(s)...
done
Example 1 - until loop
#!/bin/bash
END_CONDITION=end
until [ "$var1" = "$END_CONDITION" ]
do
echo "Input variable #1 "
echo "($END_CONDITION to exit)"
read var1
echo "variable #1 = $var1"
echo
done
Example 2 - C-style
#!/bin/bash
LIMIT=10
var=0
until (( var > LIMIT ))
do
echo -n "$var "
(( var++ ))
done
exit 0
Controlling the loop
- Break
- Continue
Break
- Exits the step in the loop
- Finishes the rest of the looping
#!/bin/bash
LIMIT=20
a=0
while [ "$a" -le "$LIMIT" ]
do
a=$(($a+1))
if [ "$a" -gt 2 ]
then
break # Skip entire rest of loop.
fi
echo -n "$a "
done
Continue
- Exits the step in the loop
- Doesn't finish the rest of the looping
#!/bin/bash
LIMIT=19
echo "Printing Numbers 1 through 20 (but not 3 and 11)."
a=0
while [ $a -le "$LIMIT" ]
do
a=$(($a+1))
if [ "$a" -eq 3 ] || [ "$a" -eq 11 ]
then
continue
fi
echo -n "$a "
done
# Exercise:
# Why does the loop print up to 20?
More than 9 Parameters - shift
shift N
- Shifts positional parameters to the left by N
- from 'N+1' to '$#' are renamed to variable names from '$1' to '$# - N+1'
- if a command takes 10 args, N is 4, then: $4 => $1, $5 => $2, etc - $10 => $7 and orig $1, $2, $3 are thrown away
- for N = 0 or N > $#, it does nothing
- by default N=1
Manual shift example
#!/bin/bash
if [[ $# -lt 3 ]]
then
echo "Try give more than 3 args...";
exit 1
fi
echo $*
shift 3
echo $*
Creating Menus
- Interactive programs
- User select
- PSs
- User select
User select
select variable [in list]
do
command...
break
done
PS1-4
export PS1="\u@\h \w> "
export PS2="continue-> "
PS3='Choose your favorite vegetable: '
export PS4='$0.$LINENO+ '
Exercise
Sub-scripts and Functions
function function_name {
command...
}
function_name () {
command...
}
- Local variables
- Without parameters
- With parameters
- Examples - /etc/wpa_supplicant/functions.sh
Functions Con't
updateMeViaFunc=''
function_name () {
local funcVa='I will die outside'
echo "First param was: $1"
echo "Called from the inside: $funcVa"
updateMeViaFunc="I'm returned from function too"
return 0
}
function_name "myParam"
echo "I'm returned from function: $?"
echo "Called from the outside: $funcVa"
echo "Global variable changed by function: $updateMeViaFunc"
Sub-scripts
source scriptname.sh
. scriptname.sh
Exercise
Advanced Commands
- Test operators
- Operators
- Comparison operators
Test file
- -e exists ( file or directory both true )
- -s file not zero size
Test the file type
- -f regular file ( not directory, or device file)
- -d is directory
Test file attributes
- -r file has read permission (for the user running the test)
- -w file has write permission (for the user running the test)
- -x file has execute permission (for the user running the test)
The assignment operator
# assignment
var=27
category=minerals
Arithmetic operators
let "z=5**3" # 5 * 5 * 5
echo "z = $z" # z = 125
bash$ expr 5 % 3 # 2
let "var += 5"
let "var -= 4"
let "var *= 5"
let "var /= 4"
let "var %= 4"
Arithmetic Expansion
Translating a string into a numerical expression backticks, double parentheses, or let.
z=`expr $z + 3`
z=$((z+3)) # Not to be confused with command substitution. $()
let "z = z + 4"
echo $z
Operators operations on bits (bitwise operators)
<< # left shift 1 bit ( x2 )
<<= # left-shift-equal
let "var <<= 2" # results in var left-shifted 2 bits (multiplied by 4)
>> # bitwise right shift (divides by 2 for each shift position)
>>= # right-shift-equal (inverse of <<=)
& # bitwise AND
&= # bitwise AND-equal
| # bitwise OR
|= # bitwise OR-equal
~ # bitwise NOT
^ # bitwise XOR
^= # bitwise XOR-equal
Logical operators
# ! NOT
if [ ! -f $FILENAME ]
then
...
# && AND
if [ $condition1 -a $condition2 ]
if [ $condition1 ] && [ $condition2 ]
if [[ $condition1 && $condition2 ]] # Also works.
# Note that && operator not permitted inside brackets of [ ... ] construct.
# || OR
if [ $condition1 -o $condition2 ]
if [ $condition1 ] || [ $condition2 ]
if [[ $condition1 || $condition2 ]] # Also works.
# Note that || operator not permitted inside brackets
Numeric constants
let "dec = 32"
echo "decimal number = $dec" # 32
# "0"
let "oct = 032"
echo "octal number = $oct" # 26
# "0x"
let "hex = 0x32"
echo "hexadecimal number = $hex" # 50
# BASE#NUMBER
let "bin = 2#111100111001101"
echo "binary number = $bin" # 31181
Comparing arithmetic using the command if
if [ "$a" -ne "$b" ]
then
echo "$a is not equal to $b"
echo "(arithmetic comparison)"
fi
Integer comparison operators
if [ "$a" -eq "$b" ]
if [ "$a" -ne "$b" ]
if [ "$a" -gt "$b" ]
if [ "$a" -ge "$b" ]
if [ "$a" -lt "$b" ]
if [ "$a" -le "$b" ]
(("$a" < "$b"))
(("$a" <= "$b"))
(("$a" > "$b"))
(("$a" >= "$b"))
Comparing strings
Always quote a tested string.
if [ "$a" = "$b" ]
if [ "$a" != "$b" ]
if [ -z "$String" ] # zero length (null)
if [ -n "$String" ] # not null
Comparing the complex (and, or)
if [ "$a" -eq 24 -a "$b" -eq 47 ]
if [ "$a" -eq 98 -o "$b" -eq 47 ]
if [[ "$v1" -gt "$v2" ]] || [[ "$v1" -lt "$v2" ]] && [[ -e "$filename" ]]
Regular Expressions
- Commonly used in scripts, such as grep, sed and awk.
- As of version 3, Bash has acquired its own RE-match operator: =~.
Know RE
- A character set
- An anchor - ^, $
- Modifiers - *, (), \, []
*,.,^,$
- "1133*" : 113, 1133, 1133333...
.
- "13." : 1133, 11333
*,.,^,$
- "^" : line start
^,$
- "$" : line end "XXX$"
- "^$": empty line
[...]
- "[xyz]"
- "[c-n]"
- "[B-Pk-y]"
- "[a-z0-9]"
- "[^b-d]"
- "[Yy][Ee][Ss]" : yes, Yes, YES, yEs ..
- "[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]" : NNN-NN-NNNN
\
- "\$"
- "\\"
\<\>
word boundary
"\<the\>" matches "the," but not "them," "there," "other," etc.
Extended RE +
+
"+" matches one or more of previous RE
echo a111b | sed -ne '/a1\+b/p'
echo a111b | grep 'a1\+b'
\{\}
number of occurrences
# 5 digits exact
echo -e "23\n2345\n23413\n234" | grep "[0-9]\{5\}"
if [[ $input =~ ^[0-9]{3}-[0-9]{2}-[0-9]{4}$ ]]
(),|
- () group REs
- | alternatives
echo -e "read\nreed\nraad" | grep -E 'r(ee|aa)d'
getopts Command
- Parses command-line arguments passed to the script.
- It permits passing and concatenating multiple options and associated arguments to a script
- scriptname -xyz -w /var/spool
- Argument pointer($OPTIND), optional argument attached to an option ($OPTARG)
- ':' after option name says it has associated argument
- Usually looped with 'while' to process options and arguments one at a time
- Provided arguments must be preceded by dash (-), lacks condition brackets
- External alternatives: getopt external command, getopt library function
getopts Command example
# Here we observe how 'getopts' processes command-line arguments to script.
# The arguments are parsed as "options" (flags) and associated arguments.
# Try invoking this script with:
# 'scriptname -mn'
# 'scriptname -oq qOption' (qOption can be some arbitrary string.)
# 'scriptname -qXXX -r'
#
# 'scriptname -qr'
#+ - Unexpected result, takes "r" as the argument to option "q"
# 'scriptname -q -r'
#+ - Unexpected result, same as above
# 'scriptname -mnop -mnop' - Unexpected result
# (OPTIND is unreliable at stating where an option came from.)
#
# If an option expects an argument ("flag:"), then it will grab
#+ whatever is next on the command-line.
NO_ARGS=0
E_OPTERROR=85
if [ $# -eq "$NO_ARGS" ] # Script invoked with no command-line args?
then
echo "Usage: `basename $0` options (-mnopqrs)"
exit $E_OPTERROR # Exit and explain usage.
# Usage: scriptname -options
# Note: dash (-) necessary
fi
while getopts ":mnopq:rs" Option
do
case $Option in
m ) echo "Scenario #1: option -m- [OPTIND=${OPTIND}]";;
n | o ) echo "Scenario #2: option -$Option- [OPTIND=${OPTIND}]";;
p ) echo "Scenario #3: option -p- [OPTIND=${OPTIND}]";;
q ) echo "Scenario #4: option -q-\
with argument \"$OPTARG\" [OPTIND=${OPTIND}]";;
# Note that option 'q' must have an associated argument,
#+ otherwise it falls through to the default.
r | s ) echo "Scenario #5: option -$Option-";;
* ) echo "Unimplemented option chosen.";; # Default.
esac
done
shift $(($OPTIND - 1))
# Decrements the argument pointer so it points to next argument.
# $1 now references the first non-option item supplied on the command-line
#+ if one exists.
exit $?
Exercise
Using Arrays
- Newer versions of Bash support one-dimensional arrays.
Simple array
- initialized with the variable[xx] notation
area2=( zero one two three four )
area[6]=`expr ${area[11]} + ${area[51]}`
echo ${area2[0]}
Declare array
- a script may introduce the entire array by an explicit declare -a variable statement.
declare -a bigOne=( /home/jusfeel/shell-scripting/Day-1/* )
Dereference array
- To dereference (retrieve the contents of) an array element, use curly bracket notation, that is, ${element[xx]}.
for f in ${bigOne[@]}
do
echo $f
done
Exercise
Here document
#!/bin/bash
if [ $# -lt 1 ]; then
echo "Usage: $0 package(s)"
exit 1
fi
while (($#)); do
sudo apt-get install "$1" << CONFIRM
y
CONFIRM
shift
done
Exercise
Batch Stream EDitor - sed
- Performs basic transformations on text read from a file or a pipe
- The result is sent to standard output
- Has no output file specification, we can use output redirection
- sed option 'some/expression' file_to_process > sed_output_in_a_file
- Does not modify the original input
- Filters text that it gets from a pipeline feed (vi and ed don't)
- We don't need to interact with the editor while it is running (batch editor)
- Used in scripts, greatly easing repetitive editing tasks (esp. replacement of text in a large number of files)
Example file content
This is the first line of an example text. It is a text with erors. Lots of erors. So much erors, all these erors are making me sick. This is a line not containing any errors. This is the last line.
sed delete, /d
cat -n example
sed '/erors/d' example
sed -n '/^This.*errors.$/p' example
sed '2,4d' example
sed '3,$d' example
sed -n '/a text/,/This/p' example
sed print, /p
sed '/erors/p' example
sed suppress, -n
sed -n '/erors/p' example
sed -n '/a text/,/This/p' example
sed file, -f
sed Multiple Input
sed Find and Replace
sed 's/erors/errors/' example
sed 's/erors/errors/g' example
sed 's/^/> /' example
sed 's/$/EOL/' example
sed -e 's/erors/errors/g' -e 's/last/final/g' example
sed Examples
grep sed /etc/init.d/*
Text File Processing - awk
- Yet another popular stream editor
- a pattern scanning and processing language
- Usually implemented as GUI version like 'gawk', etc
- To search files for lines or other text units containing one or more patterns
- When a line matches one of the patterns, special actions are performed on that line
- Different from programs in most other languages, which are "procedural"
- "data-driven": you describe the data you want to work with and then what to do when you find it
- You have to describe, in great detail, every step the program is to take
- Easy to read and write
The awk Programming Tool
run awk = specify an awk program = tells awk what to do
- The program consists of a series of rules
- Each rule specifies
- one pattern to search for
- and one action to perform upon finding the pattern
- It may also contain advanced features:
- function definitions, loops, conditions and other programming constructs
- Ways to run awk:
- for the short program, run it on the command line
awk PROGRAM inputfile(s)
- for regular multiple changes and on multiple files, put the awk commands in a script
awk -f PROGRAM-FILE inputfile(s)
- for the short program, run it on the command line
Pattern Matching
- The condition may be:
- a regular expression
- a test of a variable
- an arithmetic expression
- or anything that produces a non-zero or nonempty result
- It may represent a range by giving two conditions separated by a comma
- once a line matches the first condition, the action is performed until a line matches the second condition
- Special conditions, BEGIN and END.
- BEGIN is performed before any lines are read
- END action is performed after all the lines have been read or another action executes an exit statement
- If there is no condition(can be missing/omitted), the action is applied to all lines
Processing input
- Each line is split into fields based on the contents of the variable FS
- FS by default is any whitespace
- Fields are numbered: $1, $2, ...
- $0 contains the entire line
- Variable NF contains the number of fields in the line
Range Patterns
NR == 10, NR == 20 (NR - current line number)
Action Statements
- Can be any computation task:
- modify the input line
- save it in a variable
- it can perform a calculation on it
- it can print some or all of the line
- can actually do anything else you can think of
- Like the condition, action may be missing/omitted
- If there is no action, matching lines are printed
awk Examples
awk example 1
'print' command
df -h | awk '{ print $2 " " $4 }'
Exercise
References
Exercises
0. Install 'git' and create new repository in '~/Documents/scripts' folder. - sudo apt install git - cd ; mkdir Documents/scripts ; cd Documents/scripts - git init ; git add . ; git commit -m "my own scripts generator" - git config --global user.name "foo bar" ; git config --global user.email "foo@bar.com" - git commit -m "my own scripts generator" ; git log Keep our generator.sh versioned with git. 1. Prepare aliases for those commands: 1.1. find /etc/ -name apache 1.2. git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit 2. Create script 'generator.sh': - it should add '#!/bin/bash' to the file - change permission (x) - echo message "Done." 3. Extend our generator: - it should take as an argument the name of the file - pass as a second argument name of the catalog in which you want to save the file 4. Improve our generator: - add usage info with if statement 5. Change the generator: - test how many variables user provided - allow to provide 1 or 2, but no 0 arguments - provide folder and file existence checks - if folder doesn't exist ask the user if he wants to create it or not (HINT: use 'read' command) 6. Add menu to our generator - '0', '1', '2' and 'Q' should be the choice list -- 0 no arguments -- 1 file name only -- 2 file and folder name -- Q quit the script 7. Create a variable, which will be an array with names of our scripts: - echo all elements from this array - add one more element to this array, but do it in a smart way(check how long this array is) - echo only last element from this array 8. Prepare even smarter version of generator: - replace repetitive code with a function(s) - create 'sources.sh' file and place the function(s) there 8.1. Make another generator - It should allow user to choose: -- if he wants to have default constructs in it (if, case, function, loops) -- which of those constructs -- how many of them 9. Create script 'howmany' which will use two options: - '-a' will count how many different users are logged in - '-b' will show how many cores/processors are available on server 10. 'grep' exercise Find all users who have no login option via terminal a) do it without 'grep' command (create small script) b) use 'grep' c) compare speed of both ways ('time' command), what can you say? 10.1. http://ebible.org/kjv/ Prep similar example with the ASCII file from above link. Find all occurrences of word 'Jesus'. Do it with 'grep' and 'sed'. Compare results with 'time'. 11. Search apache logs for keyword (for example "error") Do it in loop 'for' 12. Do the script in which you search for all files with specific extension. Create function 'search' and it should use parameter with extension. Script should take extension as an argument. Create a variable 'testy' inside of the function and save extension in it. Echo "$testy" outside of the function after invoking it. 13. Add task to crontab. It should 'ls' into file 'list'. 14. Make a script which will allow the user to choose about what file should be removed. Use 'here document'. 15. Use file 'example' and program 'awk': a) - take only the first 2 words from each line - add 2 tabulators between these 2 words - add 'Meow!' at the end of each line b) - prepare parameter and pass 'Meow!' into awk program via this parameter - provide comment message after execution of awk program 16. Web-service example a) client(bash script) should call this end-point 'http://www.youtypeitwepostit.com/api/' b) ask about post "Squidly!" and get the result in 'json' format c) search in json response for post's date and get the day and month from it's value d) print nice message like this: "Oops! Squidly pooped himself ..eee.. made a lot of ink on 23rd of July" e) (*) migrate the whole 'data' into 'drupal' website -- enable the 'blog' module and create one blog (monkey job, just clicking) -- prepare 'MySQL' query (REAL GEEKY STUFF!) -- use drupal's 'drush' to execute sql query from our bash script (lazy way for lazy bastards like me) 17. Install debugger and play with it ( http://bashdb.sourceforge.net/ ) - do some specific mistakes in one of our generators and test them with debugger -- syntax error -- typos -- missing function definition - test some of these http://www.tldp.org/LDP/abs/html/abs-guide.html#GOTCHAS