Bash Scripting for n00bz

Bash
Bash is a command language interpreter which is widely used on various operating systems, and is the default command interpreter on most GNU/Linux systems. The name stands for Bourne-Again SHell.

Shell
Shell is a macro processor which allows for interactive or non-interactive command execution.

Scripting
Scripting allows for commands to be automatically executed that would otherwise be executed manually one-by-one.

What is shell
The terminal window contains shell, and shell allows you to use commands that interact with the computer. Tasks like storeing data, processing information, and various other simple or even complex tasks.

Examples of these commands: date, cal, pwd, or ls followed by the enter key.

What is scripting
When running these individual tasks becomes tedious and you want to be able to execute a bunch of commands together, that's when scripting comes in.

For example, we could write a script with the above example commands like so:

task.sh date cal pwd ls Once you have written this, we can make the file executable using the chomd -x command. Now your script can be run by typing ./task.sh
 * 1) !/bin/bash

With scripting, any shell command can be automated.

We can also automatically execute shell scripts daily at any time by using cron time-based job scheduler and store the script's output to a file every time it is executed.

What is Bash?
Bash is the default interpreter on many GNU/Linux systems, so we could have run task.sh without the initial shebang command. However is it good practice to define the shell interpreter to be used explicitly like we did above.

Because there are various other shell interpreters out there, such as Korn shell and C shell. To see what your default interpreter is simply run: echo $SHELL To define your script's interpreter as Bash, first we must locate a full path to its executable binary using the which command. Then prefix with a shebang (#!) and insert it as the first line of your script (like we did in the 'task.sh' example.

File names and permissions
In order to run a script as an executable you need to run chmod -x  cammand. By default, any newly created files are not executable regardless of its file extension.

In fact, the file extension on GNU/Linux systems mostly doesn't mean anything apart from the fact that upon execution of the ls command it is immediatley clear that the file with the extension .sh is a shell script, and a file with .jpg is a lossy compressed image.

You can use the file command to identify the type of a file.

Script Execution
In the previous example we define how the script is interpreted by defining the shebang at the beginning of the script.

Another way we can execute scripts is by calling the bash interpreter explicitly: user@user ~ $ bash script.sh Doing this means we don't need to define the shebang in the script because we are calling the bash executable binary explicitly, so the content of the script is loaded and interpreted as bash shell script.

Relative vs Absolute path
GNU/Linux offers a simple compass tool to help navigate through your filesystem with the command pwd. When executed will always print your current location.

An absolute path is the location of a file or directory from the root directory.

A relative path is defined as the path related to your present working directory (pwd)

Simple 'Hello World' script.
echo "Hello World"
 * 1) !/bin/bash

Basic backup shell script
This next script can be used to backup our user home directory.

To do this we will be using the tar command with options -czf in order to create a compressed tar ball of the entire home directory. tar -czf /tmp/myHome_directory.tar.gz /home/linuxconfig c - Create a new archive
 * 1) !/bin/bash

z - Filter the archive through gzip

f - Use archive file or device archive

Example using variables
greeting="Welcome" user=$(whoami) day=$(date +%A) echo "$greeting back $user! Today is $day, which is the best day of the entire week!" echo "Your Bash shell version is: $BASH_VERSION. Enjoy!" Using variables we can enhance our backup script to prodice a more meanigful output file name by incorporating a date and time when the backup on our home directory was successfully performed. As well as allowing the script to detect the current user who is running the script. user=$(whoami) input=/home/$user output=/tmp/${user}_home_$(date + %Y-%m-#d_%H%M%S).tar.gz tar -czf $output $input echo "Backup of $input completed! Details about the output backup file:" ls -l $output This script introduces yes another concept ${parameter} which is called parameter expansion.
 * 1) !/bin/bash
 * 1) Variables.
 * 1) $BASH_VERSION is an internal variable defined as part of your shell.
 * 1) !/bin/bash
 * 1) Script used to backup a user's home directory to /tmp/.

In our case, curly braces {} are required because our variable $user is followed by characters which are not part of its variable name.

Parameter Expansion
The basic form of parameter expansion is ${parameter}. The value of parameter is substituted. The parameter is a shell parameter or an array reference. The braces are required when parameter is a positional parameter with more that on digit, or when parameter is followed by a character that is not to be interpreted as part of its name.

Input, Output and Error Redirections
Normally commands executed on GNU/Linux command line either produce output, require input or throw an error message. This is a fundemental concept for shell scripting as well as for working with GNU/Linux's commands in general.

Executing a command will result in one of the three following outcomes: Let's say for example we are trying to run the command ls -l foobar when we do not have a file called 'foobar'.
 * 1) The command will produce an expected ouput.
 * 2) The command will generate an error.
 * 3) The command might not produce any output at all.

If we run this it will produce a standard error output (stderr). But if we have a file called 'foobar' we will produce standard output (stdout).

The difference between stdout and stderr output is important as it allows up to a redirect output separately.

the > notation is used to redirect stdout to a file and 2> notation is used to redirect stderr and &> is used to redirect both stdout and stderr.

Now we can adjust our script again to eliminate any unwanted stderr message by redirecting it with 2> notation to /dev/null. Think of /dev/null as a data sink which discards any data redirected to it. user=$(whoami) input=/home/$user output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz tar -czf $output $input 2> /dev/null echo "Backup of $input completed! Details about the output backupfile:" ls -l $output script WITHOUT stderr handling: $ ./backup.sh tar: Removing leading `/' from member names Backup of /home/linuxconfig completed! Details about the output backup file: -rw-r--r-- 1 linuxconfig linuxconfig 8778 Jul 27 12:30 /tmp/linuxconfig_home_2017-07-27_123043.tar.gz script WITH stderr handling: $ ./backup.sh Backup of /home/linuxconfig completed! Details about the output backup file: -rw-r--r-- 1 linuxconfig linuxconfig 8778 Jul 27 12:30 /tmp/linuxconfig_home_2017-07-27_123043.tar.gz See that the tar: Removing leading `/' from member names doesn't get printed anymore, because it is sent to stderr descriptor and now will get sent to /dev/null.
 * 1) !/bin/bash
 * 1) Send stderr output to the trash.

Another descriptor bash shell also has is an input descriptor called stdin. Generally terminal input comes from a keyboard. Any keystroke you type is accpeted by stdin.

The alternative method is to accept command input from a file using < notation. Say we were to feed cat command from the keyboard and redirect the output to file1.txt. echo "testing..." > testFile.txt If you run a cat command on testFile.txt you will get testing... printed out.

You can also accept command input from a file using the < notation. Say we were feeding a cat command and redirecting the output