BASH scripting chapter one

 

From Wikipedia

What is bash?

Bash is short for the ‘Bourne Again Shell’. It’s probably GNU Unix’s most popular shell. A shell is a program to run other programs. In addition, the BASH shell supports a scripting language, that lets a programmer automate repetitive shell tasks. Instead of having to type the same thing into the shell over and over again, you write a BASH script that will do those things for you. If you want some more background on BASH, read https://en.wikipedia.org/wiki/Bash_(Unix_shell).

Or according to Wikipedia, “a shell lets a user direct the operation of the computer by entering commands as text for a command line interpreter to execute, or by creating text scripts of one or more such commands”. https://en.wikipedia.org/wiki/Unix_shell
If you are familiar with opening a terminal, and typing a few commands like ‘ls’ or ‘pwd’, then you’ve executed a command in a shell. (And it was probably in a BASH shell.) Learning to script with BASH will let you tie these actions together, which is especially helpful for automating repetitive tasks, or for remixing existing programs on your computer to make your own special home-brew programmatic sauce.

How to install bash?

BASH is normally already installed on Linux or Mac’s. If you open your shell/terminal, type:

echo $0

This should print something like ‘bin/bash’. You might be using a different shell. zsh or something else.

If you are on Windows, then BASH is not pre-installed. There’s a few ways to get it. One way is to install the new Linux subsystem. Or you can install Cygwin or MingW. Or, my favourite, install Git for Windows and then select the ‘install additional unix tools to the command line’ during the installation process. https://git-for-windows.github.io/

If you are on Windows, then I recommend using PowerShell. To access BASH, after you’ve installed it, you can type bash or sh.

How to mark something as a bash script.

A BASH script is a text file. Open up your text editor and type in the following:


#!/bin/bash
echo "hello scripting world."

The very first line needs to be #!/bin/bash. In unix, this marks that the file is executed with the BASH interpreter. It’s called a ‘shebang’. This helps other programs know what to execute the file with. For example, if the file is a python file, then you would instead supply the path to the python interpreter in the shebang. E.g. your text file would start with:


#!/user/bin/python3
print("hello python world.")

How to run a bash script.

Save it, call it ‘hello.sh’. Open the terminal in the directory the script is in. Next, we need to make sure that we have privilege to execute the script.

On Windows you’ll need to make sure that you can execute scripts. You do this in PowerShell by setting the execution policy. You will need to start PowerShell in administrative mode initially. Then type:

Set-ExecutionPolicy Unrestricted

This tells Windows that you want to run scripts. Before Windows would only allow the execution of scripts with verified by a HASH a known developer. Now, it will run stuff without those HASHES. Close the PowerShell in administrative mode. You don’t need administrative mode any more. And then open a new PowerShell (not in admin mode) and check the execution policy. Type:


Get-ExecutionPolicy

It should echo back “Unrestricted”. If you want more information about execution policies, see: https://technet.microsoft.com/en-us/library/ee176961.aspx.

If you are on Linux, you don’t need to set your execution policy. But, you do need to make sure that the new file, “hello.sh”, is executable. In the terminal, type chmod 755 hello.sh. This will mean that you can execute the script.

Then, to run the script with BASH type:


sh hello.sh

Or, you might just get away with typing:


./hello.sh

It should print to the terminal:


hello scripting world

An example of a slightly more complex SHELL script “MOVE” command wrapper

#!/bin/bash
echo "MOVE WRAPPER SHELL SCRIPT"

if [ "$#" -lt "2" ]; then
echo "script name: $0"
echo "requires 2 args. arg1 = file to move. arg2 = move to"
exit 1

else
echo "moving '$1'"
echo "to '$2'"

mv "$1" "$2"

if [ "$?" -eq 0 ]; then
echo "SUCCESS"
else
echo "ERROR"
fi

fi

Where to find BASH documentation.

Being so popular, there are a lot of resources available. But, the definitive text, as far as I know, is the GNU bash documentation. View it here: https://www.gnu.org/software/bash/manual/bash.html.

Brian FOX, a software developer, wrote BASH for GNU. It is the original implementation, and presumably there aren’t any other implementations worth caring about.

I have found the GNU documentation for BASH very good, and detailed. Check it out.

I also recommend a UDEMY course I used to learn BASH: https://www.udemy.com/bash-scripting/
These are essentially my enhanced notes. Notes I made as I learnt BASH over the course of a few weekend nights. ENJOY 🙂

BASH variables

One of the most important things in any programming language is storing values. If you can’t store a value, then how can your program remember anything?

WARNING THINGS I FIND WEIRD ABOUT BASH

I’m used to a rich scripting language like PYTHON. Something you can develop complex programs with.
* BASH is not this.
* It doesn’t seem to have the idea of a class.
* You cannot import other BASH scripts. So, each BASH script is independent.
* You can’t return values from functions except for an integer between 0 and 255.
* BASH is very focused on exit codes. It is geared to automate the use of other programs. You don’t try create a GUI with BASH.
* So how could one BASH script pass a value to another BASH script? Ahh, ends up that there are globals every where by default. This means, KEEP YOUR SCRIPT SHORT. Anything longer than 100 lines, move into PYTHON/PERL.
* BASH wraps other programs, like MOVE (mv) or LIST (ls). BASH can access the standard input, standard error. This way it can work with variables from other scripts and programs. (I think.)
* The errors you get back are more cryptic that Python. For instance, if you mess up the syntax, the error’s aren’t that great for a beginner. No traceback, for instance. (Think of opposite of the uselessly verbose Java traceback that is printed. BASH is the opposite. It’s terse.)

syntax-error.sh

#!/bin/bash
???? opps

BASH shell output

$sh syntax-error.sh
syntax-error.sh: line 2: ????: command not found

BASH just went ‘????’ is potentially a command. There is no in front of $????. So it’s not a variable I hold. Then it attempts to find ‘????’ as something it can execute on the environment path.

That’s not a terrible error message. But, the syntax for the unfamiliar around the if statement.

syntax-error.sh

#!/bin/bash
if [ 0 -eq 0 ]
echo "zero equals zero"
else
echo "zero != zero"
fi

BASH shell output

$sh syntax-error.sh
syntax-error.sh: line 4: syntax error near unexpected token "else"
syntax-error.sh: line 4: "else"

I don’t find ‘syntax error’ near unexpected token ‘else’ very helpful. It’s pretty descriptive of what the compiler did though.

The compiler read the first three lines fine. Then it hit line four. In the abstract syntax tree, it new that it was on leaf if. it expects a then before an if. Then is an unneeded indicator. The last ] bracket should have been fine except that isn’t as efficient as using then. That’s why BASH uses ‘then’.

A better error would read:

BASH shell output

syntax-error.sh: syntax error, if [] opened on line 2 not closed with 'then' by line 4.

END OF FIRST SECTION

Leave a Reply

Your email address will not be published. Required fields are marked *