Friday, April 8, 2022

#HOWTO #Linux: Scripting

Scripting

Intro.

There are a lot of programming languages, for simplicity, we will group them:

  • Low level language (Assembler)

It's a language that can be understood by the CPU.

  • Compiled Languages such as C/C++

It’s high level code, that prior execution, must be transformed (compiled) into low-level language.

  • Interpreted Languages such as Bash, Python, Perl, C# and a lot more.

These languages use pre-compiled “programs” that “transform” (interpret)

high-level language into low-level language in real-time (runtime).


To be honest, the higher the language is, the lower its performance.
So, if we compare Python with Assembler for matter of speed, Assembler will always win.


Bash.

Look at the terminal window and say: “Hello bash!”.

Yes, your dark terminal window is handled by one of various shells: sh, bash, zsh, ash or another *sh.

The most popular of the above - bash, but it’s not guaranteed that in some linux/unix distribution there will be such.

There are two types of executable files in linux (execute permission set):

  1. Compiled low-level executable, also known as ELF binary

  2. Text-file with script program of the supported languages..

Script is a line-by-line execution of commands.

Almost any script looks like a text-file with instructions, while first line of the file must be similar to these:


#!/bin/bash

#!/usr/bin/python3

#!/usr/bin/ruby

#!/usr/bin/perl

#!/other/interpreter/for/this/script

#! - a.k.a. shebang is a special instruction for bash-shell, instructing which program will handle the remaining lines of the file.



“Hello world” Examples in different languages:

Bash:

#!/bin/bash


echo 'hello world!' #this is a comment

Python:

#!/usr/bin/python3


print('hello world!') #this is a comment

PHP:

#!/usr/bin/php


<?php

echo "hello world!\n"; //this is a comment

?>

Ruby:

#!/usr/bin/ruby


puts('hello world!');

That’s pretty simple, with one exclusion: the syntax (rules) of each language differs. But when you learn the syntax of one programming language it is quite easy to learn another language.

Let’s save one of the scripts to a file, set execute permission and finally execute it.

In Ubuntu linux there are at least two programs that are able to edit text files in terminal: nano and vi


Editing files with “nano”:

Open file: nano filename & edit the contents

Exit nano: Ctrl+X -> then Y to save the file

Editing files with “vi”:

Open file: vi filename

Edit: Press Insert key and edit the contents. When finished press Esc Key

Save and quit: Enter :wq then press Enter Key

In the following example, i have saved our first Bash script in /tmp/myscript.sh:

user@ubuntu:/home/user$ cd /tmp

user@ubuntu:/tmp$ nano /tmp/myscript.sh

--*--*--*--

Place inside your bash script, CTRL+X & Y to save the file.

--*--*--*--

user@ubuntu:/tmp$ ls -la myscript.sh

-rw-r--r-- 1 user user 33 Aug  8 21:47 myscript.sh

Let’s view its contents:

user@ubuntu:/tmp$ cat /tmp/myscript.sh

#!/bin/bash


echo 'hello world!'

Next, we need to set executable permissions:

user@ubuntu:/tmp$ chmod +x /tmp/myscript.sh

user@ubuntu:/tmp$ ls -la myscript.sh

-rwxr-xr-x 1 user user 33 Aug  8 21:48 myscript.sh

And finally execute it:

user@ubuntu:/tmp$ ./myscript.sh

Hello World!

Cool.


Variables

In every programming language, bash is not an exclusion, we can make some dynamic programs with use of variables.

Variables are some kind of containers, that are used to store information in computer’s memory, and allow us to access that information by some label.

Look at the code below:

var1="Hello World!"
echo "$var1"

This bash script will print out variable contents

  1. Assignment direction is from the right to the left

Value: Hello World! is being assigned to variable name: var1

  1. There are no spaces between = (equal sign) and variable name and value

  2. Variable is accessible by prepending $ character to the variable name

We can reassign a variable:

var1="Hello World!"
echo "$var1"

var1="Other value"

echo "$var1"

After this manipulation, $var1 will hold the string: Other Value.


Script Arguments

It is possible to pass some arguments to the script:

user@ubuntu:/tmp$ cat /tmp/script2.sh

#!/bin/bash


echo "This is argument $1"

echo "This is argument $2"

echo 'This is argument $3'

user@ubuntu:/tmp$ ./myscript2.sh argument1 argument2 argument3

This is argument argument1

This is argument argument2

This is argument $3

You might have noticed that argument3 was not printed, and we've got only $3. That's because we have used a single quote in an echo statement.

In bash, we use single quotes in cases when we want to store data literally.



Assigning command output to a variable


Bash has a very cool feature of inline command execution and it's output could be used to be assigned to the variable.

One example explains it better than any description:

user@ubuntu:/tmp$ var1=`whoami`

user@ubuntu:/tmp$ echo $var1

user

We can use multiple ways of achieving this, but with slightly different behavior:

user@ubuntu:/tmp$ var1=`whoami`

user@ubuntu:/tmp$ echo $var1

user

user@ubuntu:/tmp$ var2=$(whoami)

user@ubuntu:/tmp$ echo $var2

user

user@ubuntu:/tmp$ echo $($'\x77\x68\x6F\x61\x6D\x69')

user

user@ubuntu:/tmp$ echo `ls`

Try to understand differences between the following:

echo `ls`
echo $(ls)
echo "$(ls)"

Research the subject on your own. Google bash command substitution.


Loops

Loops are used when it is needed to perform identical actions multiple times on different values:

user@ubuntu:/tmp$ mkdir test

user@ubuntu:/tmp$ cd test

user@ubuntu:/tmp/test$ for var in `seq 1 5`; do touch file$var; done

user@ubuntu:/tmp/test$ ls

file1  file2  file3  file4  file5

Let's execute file command on each reated fileX:

user@ubuntu:/tmp/test$ for i in `ls`; do file $i; done

file1: empty

file2: empty

file3: empty

file4: empty

file5: empty

Another example with file input line-by-line, which counts line length in /etc/passwd file:

user@ubuntu:/tmp$ while read i; do echo $i; echo $i|wc -c;done < /etc/passwd

root:x:0:0:root:/root:/bin/bash

32

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

48

bin:x:2:2:bin:/bin:/usr/sbin/nologin

...snip…

user:x:1000:1000::/home/user:/bin/bash

39

If you place these loops in script, consider to make it look pretty:

#!/bin/bash

for i in `seq 1 5`
do
    touch file$var
done

while read i
do
    echo $i
    echo $i|wc -c
done < /etc/passwd 


Conditional flow control (branching)

Every programming language has the ability to control the execution flow depending on some IF/ELSE conditions.

Follow script will check if we execute the script with user: "user":

#!/bin/bash

if [[ "$(whoami)" == "user" ]]; then
  echo "Good! We are 'user'!"
else
  echo "We are not a 'user'"

   exit
fi

Multiple conditions with elif:

#!/bin/bash

currentUser=`whoami`
if [[ "$currentUser" == "user1" ]]; then
  echo "got user1"
elif [[ "$currentUser" == "user2" ]]; then
  echo "got user2"
else
  echo "someone else"
fi

Functions

#!/bin/bash

function printout {
  echo "$1"
}

currentUser=`whoami`
if [[ "$currentUser" == "user1" ]]; then
  printout "got user1"
elif [[ "$currentUser" == "user2" ]]; then
  printout "got user2"
else
  printout "someone else"
fi


Resume

This chapter shows you basic principles of scripting, and with some time, experience, trial and error - i hope you will be comfortable with bash.

It's up to you to master bash scripting. You may get your coding to a very high level and construct very complex algorithms.

Go and solve all challenges at https://cmdchallenge.com