Shell Scripting
Wanted to learn more about shell scripting. Since starting to learn programming, I have seen a lot of shell scripts without knowing fully how they work. I know that they are used mainly to interact with the computer file system, but I don't know why they might be useful or what I might use them for. I am creating this note to learn more about shell scripting.
Shell Scripting
Resources that I Will Use
I am going to go through The Shell Scripting Tutorial and then I am going to read Mastering Shell Scripting by Andrew Mallet.
Installation:
Installing Linux Subsystem on Windows:
I also installed the windows subsystem for Linux extension in vscode after installing Ubuntu. This extension allows you to run Linux commands in the vscode terminal.
The Shell Scripting Tutorial
- Steve Bourne wrote the original Bourne Shell which appeared in the Seventh edition Bell Labs Research version of Unix.
- Factors of a good shell script:
- clear, readable layout
- avoiding unnecessary commands
First Script:
#!/bin/sh
# This is a comment, FileName: first.sh
echo Hello Wolrd # This is a comment too
- The
#!
is a special directive which Unix treats specially. - The
#
is a comment - The
echo
command prints statements on the command line - To run the shell script, run
bash ./first.sh
Variables:
- Assign variables in bash scripts using
VARIABLE_NAME=VARIABLE_VALUE
- There should be no spaces around the
=
sign
- There should be no spaces around the
- All variables stored as strings
- Undeclared variables have a value of an empty string
- The
read
command can be used to reads user input from the command line - Variables are local to the shell script unless variables were exported and the script is running in the same shell another variables was exported in
- Good idea to wrap variables in curly brackets to know where they end / begin
read USER_NAME # read as "Frank"
touch "${USER_NAME}_file.txt" # creates a file called Frank_file.txt
This tutorial had a website that was full of ads that were slowing down my computer, and I didn't like how the tutorial has been going so far, so I am deciding to move onto Mastering Linux Shell Scripting before finishing the tutorial.
Mastering Linux Shell Scripting
Mastering Linux Shell Scripting will become your Bible and a handbook to create and edit bash shell scripts in Linux, OS X, or Unix.
What and Why of Scripting With Bash
- Aliases exist in memory as a shortcut to commands or commands with options. These aliases are used before we even check for the file
- File starts with the shebang
- The shebang instructs the system to the interpreter to execute the script
- The
$HOME/bin
directory is a good place to keep shell scripts - Commands can be executed on the command line based on the exit code of a previous script:
command1 || command2
- command2 is executed only if command1 fails in some way
command1 && command2
- Only execute command2 if command1 succeeds and issues an exit code of 0
- Take care to name files uniquely
- You can pass in variables to shell scripts
- Variables are one indexed
hello2.sh fred
-> passes in "fred" to the shell script
- Variables have a default value of an empty string
-
$*
- the wildcard contains all arguments passed to shell script
- You can escape the
$
with\$
- If we use single quoted, then the
$
has no special meaning - Statements wrapped in the
$(...)
syntax are used top evaluate the output of the inner command - The
$(...)
syntax can also be achieved by using backticks`...`
- The
Creating Interactive Scripts
- Interactive Scripts are scripts that prompts for information during the script execution
- Suppress the new line which ends the
echo
command with the-n
option - Script comments are prefaced with the
#
symbol. Anything after the # is not evaluated by the script - The Shebang is not evaluated by the script, but by the shell running the script
- The following example is probably how you should start your scripts:
#!/bin/bash
# Welcome script to display message to users on login
# Author: https://frankmbrown.net
# Date: 1/1/1971
- Review of different options for
read
andecho
- See statements below
- ping the server with
ping
- Can connect to databases and SQL servers from the command line
Conditions Attached
- Conditional statements can be written with simple command-line lists of
AND
orOR
commands together or, more often, within traditionalif
statements - Command Line lists are two or more statements that are joined using either the
AND
orOR
notations - If we have to refer to the same value more than once, then a variable is generally a good idea
- You can build simple conditions using command line lists, but as complexity increases, it is easier to create statements using
if
- If statements in shell:
if condition ; then
statement1
statement2
elif condition ; then
statement3
else
statement4
fi
- Case Statements:
- Easier than writing a bunch of if else statements that test for equality
case expression in
case1)
statement1
statement2
;;
case2)
statement1
statement2
;;
*)
statement1
;;
esac
- Case statements are good for catering to a range of letters, e.g. a-f (not so much for integers)
Creating Code Snippets
If you like using the command line, but also like some of the features associated with using graphical Integrated Development Environments (IDEs), then this chapter may reveal some new ideas to you.
- Chapter goes over how to add code snippets in vim/vi editors
- Bringing Color to the terminal:
- The following statement:
echo -e "\033[31mError\033[0m"
prints "Error" in red to the terminal - Will probably want to add colors to vscode code snippets
- RED="\033[31m"
- GREEN="\033[32m"
- BLUE="\033[34m"
- RESET="\033[0m"
- Be sure to reset the color to the default color after using it:
echo -e "${RED}Error$RESET"
- The following statement:
Alternative Syntax
- Test Command
- Testing of file exists:
test -e PATH_TO_FILE
- Testing if file exists and does not have a special purpose (special file types can be directories, pipes, links, and so on):
test -f PATH_TO_FILE
- Testing of file exists:
- Adding Logic:
test -f FILE -a -r FILE
tests whether the file is a normal file and (-a
) whether or not the file has read permissions set (-r
)
[
is a built in command same as the test command, but it requires a closing bracket- Providing Parameter Defaults
Within bash parameters, there are names spaces in the memory that allow us access to stored variables. There are two types of parameters:
1. Variables
2. Special Parameters
Special parameters are read-only and are pre-set by the shell. Variables are maintained by ourselves as well as bash.
- Variables are set by the system or by ourselves. They are not read only.
- Special Parameters are the second parameter type and are managed by the shell itself and are presented as read-only.
- The shell options can be read programmatically with the
$-
command
- The shell options can be read programmatically with the
- Providing Defaults
- We can use the test command / brackets to set default values for variables:
#!/bin/bash
name=$1
[ -z $name ] && name="Anonymous" # If an argument was not provided to the shell script, assign a default value
echo "Hello $name"
name2=${2-"Anonymous 2"} # assign Anonymous 2 to name2 if the second argument is not passed to the script
exit 0
- parameter expansion is the correct term that we should use for reading the value of variables
- When using parameter expansion, it is best to wrap the expansion in quotes -
"$FILE"
- since this controls for spaces
- When using parameter expansion, it is best to wrap the expansion in quotes -
- Advanced Test Using [[
- Double brackets is a keyword
- Arithmetic Operations using ((
- a=(( 2 + 3 ))
- You can also use arithmetic tests using ((:
(( COUNT > 1 )) && echo "Count is greater than 1"
Iterating with Loops
- Example Syntax:
#!/bin/bash
for n in $*
do
echo "Hello $n"
done
exit 0
- The break keyword is used to exit the loop processing no more entries, whereas the continue keyword is used to stop the processing of the current entry in the loop and resume processing the next entry.
- While For loops can iterate items in a list, while and until loops can iterate until a condition becomes true or false
#!/bin/bash
COUNT=10
while (( COUNT >= 0 )) ; do
echo -e "$COUNT \c"
echo -e "$COUNT \c"
(( COUNT -- ))
done ;
COUNT2=10
until (( COUNT2 < 0 )) ; do
echo -e "$COUNT \c"
(( COUNT-- ))
done ; echo
exit 0
- We can also use the read command to read from files
Creating Building Blocks with Functions
- Functions are blocks of code that exist in memory as named elements.
- Functions are checked after aliases when running commands on the command line
function show_system {
echo "The uptime is:"
uptime
echo
echo "CPU Detail"
lscpu
echo
echo "User List"
who
}
# Call type show_system to print the details of the function
# To run the function just type:
# $ show_system # in the command line
- We can pass variables into shell functions by declaring the functions in shell scripts and using the passed in command line arguments as parameters in the functions.
Introducing sed
The sed command is the Stream Editor and [it] opens the file line by line to search or edit the file contents.
Global Regular Expression Print (grep), or whet we more commonly call the command grep, is a command line tool used to search globally (across all the lines in a file) and print the results to STDOUT. The search string is a regular expression.
-
grep
-i
: case insensitive flag- Regular Expressions are the same across all languages, and I have studied them in depth already
sed
- Can be used to print matches (p), replace matches (s), and run in place updates (-i).
Skipping the Rest of the Book
- The rest of the book goes over Apache Web Servers, the awk programming languages, and using perl/python as alternative scripting languages
- I use an nginx web server and will learn more about Apache if I ever need to.
- The awk programming language is used for text processing and this can be done in many different languages
Unix Commands
Below, expressions in brackets, e.g. [-t]
, communicate options for a command.
echo STATEMENT
- Print out a STATEMENT to the command line
read [-[s]nINTEGER] [-p STATEMENT VARIABLE]
- Read user input from the command line
- The
-p STATEMENT VARIABLE
allows you to output text before the read command reads in the input. The input of read is saved in the VARIABLE. - The
[-[s]nINTEGER]
option limits the number of characters to read to the number of INTEGER - By including the s "silent" option, the input characters will not be printed to the command line
.
- Run a script like
. PATH_TO_SCRIPT
to keep the variables that were previously exported by a shell script
- Run a script like
touch FILE_NAME
- creates a
lsb_release
- Get the operating system being used
echo $BASH_VERSION
- Get the current version of bash
type COMMAND [-t]
- Display the type of command for a given word entered at the command line
-t
- Only display the type in the output
- Types of commands:
- Alias
- Function
- Shell built in
- Keyword
- File
~
- Tilde expression
- The value of $HOME
- Wine FILENAME
- Open up a file in the terminal in Ubuntu
clear
- clear terminal
exit NUMBER
- used to leave or exit the script
- The exit code is supplied as an integer (NUMBER). A value of anything but 0 indicates that an error has occurred
chmod [+r] [+w] [+x]
- change the access permissions and the special mode flags of file system objects
+r
- Reading writes, also known as R-bit
+w
- Writing right, also known as W-bit
+x
- Execution writes; also known as X-bit
$?
- check the exit code of a previously run script
nano FILE
- Open the FILE in the built-in text editor in the terminal
cp FILE_1 FILE_2
- Make a copy of FILE_1 and save it as FILE_2
basename FILE_PATH
- extracts the name of the file from the name of the path
bash filename [-v] [-x]
- Runs the shell script provided by filename
- The -v option gives you the verbose output from the script and the detailed information about the way the script is evaluated line by line
- The -x option displays the commands as they get executed
- This helps when there is conditional logic in the script
test [!] EXPRESSION
- The Unix test command evaluates the EXPRESSION parameter
- See the test expression arguments below
- test can be replaced by the square bracket notation [ EXPRESSION ]
Test Options
Argument |
Returns |
---|---|
-b | is a block character file |
-c | is a special character file |
-d | is a directory |
-e | exists |
-f | is a regular file |
-g | has the Set Group ID bit set |
-h | is a symbolic link |
-k | has the sticky bit set |
-L | is a symbolic link |
-p | is a named pipe |
-r | is readable by the current process |
-s | has a size greater than 0 |
-t | FileDesciptor is open and associated with a terminal |
-u | has the Set User ID bit set |
-w | has the write flag on |
-x | has execute flag on |
Operators |
|
-a |
AND, e.g. test expression1 -a expression2
|
-o |
OR, e.g. test expression1 -o expression2
|
String Arguments |
|
-n STRING | Tests to see if a string has a value |
-z STRING | Tests to see if the string has no value |
Number Arguments |
|
-ne | not equal |
-gt | greater than |
-ge | greater or equal |
-lt | less than |
-le | less or equal |
Unix Variables
$HOME
- The current user's home directory
$PWD
- The present working directory
$BASH
- The version number of
bash
- The version number of
$BASH_VERSION
- The version number of the current
bash
process
- The version number of the current
$EUID
- The effective user ID of the current user, which is assigned during startup
$HOSTNAME
- The name of the current host
$PATH
- The colon-separated list of directories where shell will look for commands
$PPID
- The process ID of the shell's parent
Tar Functions
Supported Function | Description |
---|---|
tar -c | Create a new archive |
tar -A | Append a tar file to another archive |
tar -r | Append a file to an archive |
tar -u | Update files in an archive if the one in the filesystem is newer. |
tar -d | Find the diff between an archive and the filesystem |
tar -t | List the contents of an archive |
tar -x | Extract the contents of an archive |
While specifying the function, the '-' prefix is not required, and the function can be followed by other single letter options. |
Tar Options
Tar Option | Description |
---|---|
-j | Read or write archives using the bzip2 compression algorithm |
-J | Read or write archives using the xz compression algorithm |
-z | Read or write archives using the gzip compression algorithm |
-a | Read or write archives using the compression algorithm determined by the archive file name |
-v | Perform the operations verbosely |
-f | Specify the filename for the archive |
Conclusion: The archive format of the Tar command in Unix preserves the directory structure, and the file system attributes such as permission and dates.
Conclusion
I need to learn more about Operating Systems / Computer Architecture / Computer Networking to better understand Linux probably.
Comments
There are currently no comments to show for this article.