Linux scripting for dummies

Shell scripting

We have tried to write a reference guide for Linux and Unix Admins.
 

Getting started

Starting an script.

The folling code is the typical "helloWorld" program writen in shell scripting:

#!/bin/bash
# do something like 
echo "hello world!!!"
exit 0

The first line contains the shebang declaration. It declares which interpreter is going to be used in order to execute the script.

The second line contains a comment. It is used to write things that help others to understand what was going on your head when you where writting the script.

Third line contains a reserved word because contains the "echo" command. This command takes the first argument given and dumps it to the standard output.

Forth line the exit status mainly

"0": means okey

other value: means something went wrong...

Linux variables

Shell variables.

$$ = The PID number of the process executing the shell.
$? = Exit status variable.
$0 = The name of the command you used to call a program.
$1 = The first argument on the command line.
$n = The nth argument on the command line.
$* = All the arguments on the command line.
$# The number of command line arguments.

Environment variables

$PATH=contains the path where commands are stored.
$RANDOM= obtains a random number value
$USER=contains the variable where the logged on user is stored.
$SHELL=conatins the execution shell in use
$TERM= the type of terminal

 

Other environment variables

On any shell or any script there are a lot of variables set. You can have a list of them typing "env" on the command line. The result will contain a pair of key and value list. The left side will be the key and the rigth side will be the value.

LESSKEY=/etc/lesskey.bin
NNTPSERVER=news
INFODIR=/usr/local/info:/usr/share/info:/usr/info
MANPATH=/usr/share/man:/usr/local/man
HOSTNAME=nodo1
XKEYSYMDB=/usr/share/X11/XKeysymDB
HOST=nodo1
TERM=xterm
SHELL=/bin/bash
PROFILEREAD=true
HISTSIZE=1000
SSH_CLIENT=10.25.4.216 4706 22
MORE=-sl
SSH_TTY=/dev/pts/1
USER=root
LS_COLORS=no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;
33;01:or=41;33;01:ex=00;32:*.cmd=00;32:*.exe=01;32:*.com=01;32:*.bat=01;32:*.btm=01;32
:*.dll=01;32:*.tar=00;31:*.tbz=00;31:*.tgz=00;31:*.rpm=00;31:*.deb=00;31:*.arj=00;
31:*.taz=00;31:*.lzh=00;31:*.lzma=00;31:*.zip=00;31:*.zoo=00;31:*.z=00;31:*.Z=00;
31:*.gz=00;31:*.bz2=00;31:*.tb2=00;31:*.tz2=00;31:*.tbz2=00;31:*.avi=01;35:*.bmp=01;
35:*.fli=01;35:*.gif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mng=01;35:*.mov=01;35:
*.mpg=01;35:*.pcx=01;35:*.pbm=01;35:*.pgm=01;35:*.png=01;35:*.ppm=01;35:*.tga=01;35:
*.tif=01;35:*.xbm=01;35:*.xpm=01;35:*.dl=01;35:*.gl=01;35:*.wmv=01;35:*.aiff=00;32:
*.au=00;32:*.mid=00;32:*.mp3=00;32:*.ogg=00;32:*.voc=00;32:*.wav=00;32:
XNLSPATH=/usr/share/X11/nls
ENV=/etc/bash.bashrc
HOSTTYPE=x86_64
FROM_HEADER=
PAGER=less
CSHEDIT=emacs
XDG_CONFIG_DIRS=/etc/xdg
MINICOM=-c on
MAIL=/var/mail/root
PATH=/sbin:/usr/sbin:/usr/local/sbin:/root/bin:/usr/local/bin:/usr/bin:/bin:
/usr/bin/X11:/usr/X11R6/bin:/usr/games:/usr/lib/mit/bin:/usr/lib/mit/sbin
CPU=x86_64
INPUTRC=/etc/inputrc
PWD=/root
LANG=POSIX
PYTHONSTARTUP=/etc/pythonstart
QT_SYSTEM_DIR=/usr/share/desktop-data
SHLVL=1
HOME=/root
LESS_ADVANCED_PREPROCESSOR=no
OSTYPE=linux
LS_OPTIONS=-A -N --color=tty -T 0
XCURSOR_THEME=DMZ
WINDOWMANAGER=/usr/bin/gnome
LESS=-M -I
MACHTYPE=x86_64-suse-linux
LOGNAME=root
XDG_DATA_DIRS=/usr/share:/etc/opt/kde3/share:/opt/kde3/share
LC_CTYPE=en_US.UTF-8
SSH_CONNECTION=10.25.4.216 4706 10.25.2.64 22
LESSOPEN=lessopen.sh %s
INFOPATH=/usr/local/info:/usr/share/info:/usr/info
LESSCLOSE=lessclose.sh %s %s
G_BROKEN_FILENAMES=1
COLORTERM=1
_=/usr/bin/env

Variables

Variables are containers where the information of the program is stored.
First the program needs to initialize the value.
Then we can work with them.

name="santiago"
echo $name

To initialize the variables, type a non reserved word and assign them a value.
Afterwards, do something with them like printing the value, storing them in disk...

Operating with variables: Bash

Addition

 export res="0"
export res=$((${res}+1)) 

Substraction

 export res="10"
export res=$((${res}-1)) 

Pipes, redirection and other stuff...

Redirection.

Each process has three type of descriptors:

- stdin: Standard Input

- stdout: Standard Output

- stderr: Standard Error
 

Stdin

Is the input that the process receives. It's expressed with the integer 1:

Stdin can be handled with the sign "<"

 mknod /tmp/passwd p
echo "admin123">/tmp/passwd  &

echo "admin123">/tmp/passwd  &
passwd bigadmin</tmp/passwd

You can read it with the command read <name_var> 

 read nombre
echo "tu nombre es ${nombre}"

 

Stdout

asdfasdfa

Stderr

asdfasdfa

 

Pipes.

asdfasdfa
asdfasdfa

Conditional statements

OPERATORS.

test -f file
True if the file is a plain file
test -d file
True if the file is a directory
test -r file
True if the file is readable
test -w file
True if the file is writable
test -x file
True if the file is executable
test -s file
True if the file contains something
test -g file
True if setgid bit is set
test -u file
True if setuid bit is set
test s1 = s2
True if strings s1 and s2 are equal
test s1 != s2
True if strings s1 and s2 are unequal
test x -eq y
True if the integers x and y are numerically equal
test x -ne y
True if integers are not equal
test x -gt y
True if x is greater than y
test x -lt y
True if x is less than y
test x -ge y
True if x>=y
test x -le y
True if x <= y
!
Logical NOT operator
-a
Logical AND
-o
Logical OR

Note that an alternate syntax for writing these commands if to use the square brackets, instead of writing the word test.

[ $x -lt $y ]   "=="    test $x -lt $y

Just as with the arithmetic expressions, Bash 2.x provides a syntax for conditionals which are more similar to Java and C. While arithmetic C-like expressions can be used within double parentheses, C-like tests can be used within double square brackets.

[[ $var == "OK" || $var == "yes" ]]

This C-like syntax is not allowed in the Bourne shell, but is equivalent to

[ $var = "OK" -o $var = "yes" ]

which is valid in both shells.

Arithmetic C-like tests can be used within double parentheses so that under Bash 2.x the following tests are equivalent:

[ $x -lt $y ]   "==" (( x < y ))

 

IF ELSE

if [ param operator param2 ]

then

<bloque codigo>

else

<bloque codigo>

fi

ELIF

if [ bl1]

then

[code1]

elif [bl2]

then

[code2]

elif [bl3]

then

[code3]

fi

 

Switch/Case

case  $variable-name  in
                pattern1)   command
                                ...
                                ..
                                command;;
                pattern2)   command
                                ...
                                ..
                                command;;
                patternN)   command
                                ...
                                ..
                                command;;
                *)             command
                                ...
                                ..
                                command;;
           esac

Loops

for.

 

 #!/bin/bash
for i in $( ls ); do
echo item: $i
done

#!/bin/bash
for ((i=100;i<=115;i+=1)); do
echo $i
sleep 1
echo $i > /dev/ttyS1
done

#!/bin/bash
for i in `seq 1 10`;
do
echo $i
done 

while

 while true
do

echo $aa

done 

 

 #!/bin/bash
for i in $( ls ); do
echo item: $i
done

#!/bin/bash
for ((i=100;i<=115;i+=1)); do
echo $i
sleep 1
echo $i > /dev/ttyS1
done

#!/bin/bash
for i in `seq 1 10`;
do
echo $i
done 

Must know commands.

Vi

awk grep cat

bc

echo mknod sort

seq date test

seq

Generates a sequence of numbers. Example:

 

dfasdf

date

Outputs the current system date.

afsdfa

 

test

Evaluates an expression returning true or false. Example:

( EXPRESSION )
              EXPRESSION is true

       ! EXPRESSION
              EXPRESSION is false

       EXPRESSION1 -a EXPRESSION2
              both EXPRESSION1 and EXPRESSION2 are true

       EXPRESSION1 -o EXPRESSION2
              either EXPRESSION1 or EXPRESSION2 is true

       -n STRING
              the length of STRING is nonzero

       STRING equivalent to -n STRING

       -z STRING
              the length of STRING is zero

       STRING1 = STRING2
              the strings are equal

       STRING1 != STRING2

       -h FILE
              FILE exists and is a symbolic link (same as -L)

       -k FILE
              FILE exists and has its sticky bit set

       -L FILE
              FILE exists and is a symbolic link (same as -h)

       -O FILE
              FILE exists and is owned by the effective user ID

       -p FILE
              FILE exists and is a named pipe

       -r FILE
              FILE exists and read permission is granted

       -s FILE
              FILE exists and has a size greater than zero

       -S FILE
              FILE exists and is a socket

       -t FD  file descriptor FD is opened on a terminal

       -u FILE
              FILE exists and its set-user-ID bit is set

       -w FILE
              FILE exists and write permission is granted

       -x FILE
              FILE exists and execute (or search) permission is granted

       -b  file
              True if file exists and is a block special file.

       -c  file
              True if file exists and is a character special file.

       -d  file
              True if file exists and is a directory.

       -e  file
              True if file exists.

       -f  file
              True if file exists and is a regular file.
       -g  file
              True if file exists and its set-group-ID flag is set.

       -h  file
              True if file exists and is a symbolic link.

       -L  file
              True if file exists and is a symbolic link.

       -n  string
              True if the length of string is non-zero.

       -p  file
              True if file is a FIFO.

       -r  file
              True if file exists and is readable. True shall indicate 
that permission to read from file will be granted, as  defined  in
              File Read, Write, and Creation .

       -S  file
              True if file exists and is a socket.

       -s  file
              True if file exists and has a size greater than zero.

       -t  file_descriptor

              True if the file whose file descriptor number is 
file_descriptor is open and is associated with a terminal.

       -u  file
              True if file exists and its set-user-ID flag is set.

       -w  file
              True  if file exists and is writable. True shall indicate 
that permission to write from file will be granted, as defined in
              File Read, Write, and Creation .

       -x  file
              True if file exists and is executable. True shall indicate 
that permission to execute file will be granted, as  defined  in
              File  Read,  Write,  and  Creation  .  If  file  is a
directory, true shall indicate that permission to search file will be
              granted.

       -z  string
              True if the length of string string is zero.

       string True if the string string is not the null string.

       s1 =  s2
              True if the strings s1 and s2 are identical.
       s1 !=  s2
              True if the strings s1 and s2 are not identical.

       n1 -eq  n2
              True if the integers n1 and n2 are algebraically equal.

       n1 -ne  n2
              True if the integers n1 and n2 are not algebraically equal.

       n1 -gt  n2
              True if the integer n1 is algebraically greater than the integer n2.

       n1 -ge  n2
              True if the integer n1 is algebraically greater than or equal to the integer n2.

       n1 -lt  n2
              True if the integer n1 is algebraically less than the integer n2.

       n1 -le  n2
              True if the integer n1 is algebraically less than or equal to the integer n2.

       expression1 -a  expression2

              True if both expression1 and expression2 are true. The -a 
binary primary is left associative. It has  a  higher  precedence
              than -o.

       expression1 -o  expression2

              True if either expression1 or expression2 is true. The -o 
binary primary is left associative.




Gui for command line

dialog is a command line util that allows us to improve the look of a shellscript

 dialog --title "Linux Dialog Utility Infobox" --backtitle "Linux Shell Script\
Tutorial" --infobox "This is dialog box called infobox, which is used \
to show some information on screen, Thanks to Savio Lam and\
Stuart Herbert to give us this utility. Press any key. . . " 7 50 ; read 

Linux Console Formatting

Linux Console (Screen)

How can I write colorful message on Linux Console? , mostly this kind of question is asked by newcomers (Specially those who are learning shell programming!). As you know in Linux everything is considered as a file, our console is one of such special file. You can write special character sequences to console, which control every aspects of the console like Colors on screen, Bold or Blinking text effects, clearing the screen, showing text boxes etc. For this purpose we have to use special code called escape sequence code.  Our Linux console is based on the DEC VT100 serial terminals which support ANSI escape sequence code.

What is special character sequence and how to write it to Console?

By default what ever you send to console it is printed as its. For e.g. consider following echo statement,
$ echo "Hello World"
Hello World
Above echo statement prints sequence of character on screen, but if there is any special escape sequence (control character) in sequence , then first some action is taken according to escape sequence (or control character) and then normal character is printed on console. For e.g. following echo command prints message in Blue color on console
$ echo -e "\033[34m   Hello Colorful  World!"
Hello Colorful  World!

Above echo statement uses ANSI escape sequence (\033[34m), above entire string ( i.e.  "\033[34m   Hello Colorful  World!" ) is process as follows

1) First \033, is escape character, which causes to take some action
2) Here it set screen foreground color to Blue using [34m escape code.
3) Then it prints our normal message Hello Colorful  World! in blue color.

Note that ANSI escape sequence begins with \033 (Octal value) which is represented as ^[ in termcap and terminfo files of terminals and documentation.

You can use echo statement to print message, to use ANSI escape sequence you must use -e option (switch) with echo statement, general syntax is as follows
Syntax
echo   -e  "\033[escape-code    your-message"

In above syntax you have to use\033[ as its with different escape-code for different operations. As soon as console receives the message it start to process/read it, and if it found escape character (\033) it moves to escape mode, then it read "[" character and moves into Command Sequence Introduction (CSI) mode. In CSI mode console reads a series of ASCII-coded decimal numbers (know as parameter) which are separated by semicolon (;) . This numbers are read until console action letter or character is not found (which determines what action to take). In above example

\033Escape character[Start of CSI3434 is parametermm is letter (specifies action)

Following table show important list of such escape-code/action letter or character

Character or letterUse in CSIExampleshSet the ANSI modeecho -e "\033[h"lClears the ANSI modeecho -e "\033[l"mUseful to show characters in different colors or effects such as BOLD and Blink, see below for parameter taken by m.echo -e  "\033[35m Hello World"qTurns keyboard num lock, caps lock, scroll lock LED on or off, see below.echo -e "\033[2q"sStores the current cursor x,y position (col , row position) and attributesecho -e "\033[7s"uRestores cursor position and attributesecho -e "\033[8u"

m understand following parameters

ParameterMeaningExample0Sets default color scheme (White foreground and Black background), normal intensity, no blinking etc. 1Set BOLD intensity$ echo -e "I am \033[1m BOLD \033[0m Person"
I am BOLD Person
Prints BOLD word in bold intensity and next ANSI Sequence remove bold effect (\033[0m)2Set dim intensity$ echo -e "\033[1m  BOLD \033[2m DIM  \033[0m"5Blink Effect$ echo -e "\033[5m Flash!  \033[0m"7Reverse video effect i.e. Black foreground and white background in default color scheme$ echo -e "\033[7m Linux OS! Best OS!! \033[0m"11Shows special control character as graphics character. For e.g. Before issuing this command press alt key (hold down it) from numeric key pad press 178 and leave both key; nothing will be printed. Now give --> command shown in example and try the above, it works. (Hey you must know extended ASCII Character for this!!!)$ press alt + 178
$ echo -e "\033[11m"
$ press alt + 178
$ echo -e "\033[0m"
$ press alt + 178

25Removes/disables blink effect 27Removes/disables reverse effect 30 - 37Set foreground color
31 - RED
32 - Green
xx - Try to find yourself this left as exercise for you :-)$ echo -e "\033[31m I am in Red"40 - 47Set background color
xx - Try to find yourself this left as exercise for you :-)$ echo -e "\033[44m Wow!!!"

q understand following parameters

ParametersMeaning0Turns off all LEDs on Keyboard1Scroll lock LED on and others off2Num lock LED on and others off3Caps lock LED on and others off

Trap