shell programming guntis bārzdiņš Ģirts folkmanis normunds grūzītis
TRANSCRIPT
Shell Programming
Guntis BārzdiņšĢirts Folkmanis
Normunds Grūzītis
Lecture outline
Shell features Helper utilities: introduction Connecting utilities with shell scripting Helper utilities in detail Piping, advanced examples Shell scripts as files, programming constructs
Bash
We will talk about bash; there might be differences for other shells bash – GNU Bourne-Again Shell Authors: Brian Fox and Chet Ramey (1989)
Free Software Foundation; a replacement for the Bourne shell
Popular (default) in different distributions To find your current (login) shell, type the command
echo $SHELL/bin/bash
Shell Features
The shell (sh) itself is defined in SUS (Single UNIX Specification) The language interpreted by the shell is also part of the standard As well as the standard utility programs (150+)
SUS derives from the POSIX.2 which is not freely available (SUS stands as IEEE Std1003.1 2001 and is identical to POSIX.2)
Note: bash is rather a dialect of the POSIX shell language Has acquired many extensions that may change the behavior of valid
POSIX shell scripts Supports a --posix switch which makes it POSIX-compliant Conforms to the POSIX standard if invoked as sh
/bin/sh
Shell features
Two types of usage: Command line - interactive Shell script, usually non-interactive
Shell scripts:"Shell Script is series of commands written in plain text
file. Shell script is just like batch file is MS-DOS but have more power than the MS-DOS batch file."
Shell features
Two types of commands: Internal commands – built in the shell interpreter
e.g. type -a cd External commands – calling other executable files
e.g. type -a ls
Almost everything applies to both command line usage and shell scripts
External commands
Execution of external programs – the most common task
girtsf@linux tmp $ ls -l /lib total 4035-rwxr-xr-x 1 root root 7488 Oct 6 12:33 cppdrwxr-xr-x 13 root root 1024 Oct 25 15:57 dev-statedrwxr-xr-x 2 root root 1024 Jun 28 09:53 evmsdrwxr-xr-x 2 root root 2048 Aug 23 15:25 iptables-rwxr-xr-x 1 root root 92716 Oct 14 13:10 ld-2.3.4.so-rwxr-xr-x 1 root root 22800 Oct 14 13:17 ld-linux.so.1...
External program: /bin/ls
External commands
The environment variable $PATH determines where to search for external programs
$ echo $PATH
/bin:/usr/bin:/usr/local/bin:/opt/bin
“:” as separator The current directory “.” is usually not included in
$PATH for security reasons
External commands
girtsf@linux tmp $ echo $PATH
/bin:/usr/bin:/usr/local/bin:/opt/bin
With /bin in path, typing “ls” suffices to run /bin/ls Example of unsetting path: girtsf@linux tmp $ unset PATH
girtsf@linux tmp $ ls
bash: ls: No such file or directory
girtsf@linux tmp $
Internal commands
A large list of built in commands, that are handled internally without running an external command Does not require forking off a separate process Needs direct access to the shell internals
Most commonly used internal command is cd, used to change the current working directory:
girtsf@linux girtsf $ cd /tmp/
girtsf@linux tmp $
Internal commands
girtsf@linux tmp $ helpGNU bash, version 2.05b.0(1)-release (i686-pc-linux-gnu)These shell commands are defined internally. Type `help' to see this
list.Type `help name' to find out more about the function `name'.Use `info bash' to find out more about the shell in general.Use `man -k' or `info' to find out more about commands not in this list.
A star (*) next to a name means that the command is disabled.
%[DIGITS | WORD] [&] (( expression )) . filename : [ arg... ] [[ expression ]] alias [-p] [name[=value] ... ] bg [job_spec] bind [-lpvsPVS] [-m keymap] [-f fi break [n] builtin [shell-builtin [arg ...]] case WORD in [PATTERN [| PATTERN]. cd [-L|-P] [dir] command [-pVv] command [arg ...]...
Aliasing
Aliasing is the process of assigning a command to a shorter “alias” This allows you to type the shorter command instead of the
longer one Aliasing is useful for changes that you want all of the time
alias rm “rm –i”
Aliasing is similar to shell function definitions dos2unix() { cat $1 | perl -pe 's/\r\n$/\n/g'; } unix2dos() { cat $1 | perl -pe 's/\n$/\r\n/g'; }
SUS: shell grammarcomplete_command : list separator | list ;list : list separator_op and_or | and_or ;and_or : pipeline | and_or AND_IF linebreak pipeline | and_or OR_IF linebreak pipeline ;pipeline : pipe_sequence | Bang pipe_sequence ;pipe_sequence : command | pipe_sequence '|' linebreak command ;command : simple_command | compound_command | compound_command redirect_list | function_definition ;compound_command : brace_group | subshell | for_clause | case_clause | if_clause | while_clause | until_clause ;subshell : '(' compound_list ')' ;compound_list : term | newline_list term | term separator | newline_list term separator ;term : term separator and_or | and_or ;for_clause : For name linebreak do_group | For name linebreak in sequential_sep do_group | For name linebreak in wordlist sequential_sep do_group ;name : NAME /* Apply rule 5 */ ;in : In /* Apply rule 6 */ ;wordlist : wordlist WORD | WORD ;case_clause : Case WORD linebreak in linebreak case_list Esac | Case WORD linebreak in linebreak case_list_ns Esac | Case WORD linebreak in linebreak Esac ;case_list_ns : case_list case_item_ns | case_item_ns ;case_list : case_list case_item | case_item ;case_item_ns : pattern ')' linebreak | pattern ')' compound_list linebreak | '(' pattern ')' linebreak | '(' pattern ')' compound_list linebreak ;case_item : pattern ')' linebreak DSEMI linebreak | pattern ')' compound_list DSEMI linebreak | '(' pattern ')' linebreak DSEMI linebreak | '(' pattern ')' compound_list DSEMI linebreak ;pattern : WORD /* Apply rule 4 */ | pattern '|' WORD /* Do not apply rule 4 */ ;if_clause : If compound_list Then compound_list else_part Fi | If compound_list Then compound_list Fi ;else_part : Elif compound_list Then else_part | Else compound_list ;while_clause : While compound_list do_group ;until_clause : Until compound_list do_group ;function_definition : fname '(' ')' linebreak function_body ;function_body : compound_command /* Apply rule 9 */ | compound_command redirect_list /* Apply rule 9 */ ;fname : NAME /* Apply rule 8 */ ;brace_group : Lbrace compound_list Rbrace ;do_group : Do compound_list Done /* Apply rule 6 */ ;simple_command : cmd_prefix cmd_word cmd_suffix | cmd_prefix cmd_word | cmd_prefix | cmd_name cmd_suffix | cmd_name ;cmd_name : WORD /* Apply rule 7a */ ;cmd_word : WORD /* Apply rule 7b */ ;cmd_prefix : io_redirect | cmd_prefix io_redirect | ASSIGNMENT_WORD | cmd_prefix ASSIGNMENT_WORD ;cmd_suffix : io_redirect | cmd_suffix io_redirect | WORD | cmd_suffix WORD ;redirect_list : io_redirect | redirect_list io_redirect ;io_redirect : io_file | IO_NUMBER io_file | io_here | IO_NUMBER io_here ;io_file : '<' filename | LESSAND filename | '>' filename | GREATAND filename | DGREAT filename | LESSGREAT filename | CLOBBER filename ;filename : WORD /* Apply rule 2 */ ;io_here : DLESS here_end | DLESSDASH here_end ;here_end : WORD /* Apply rule 3 */ ;newline_list : NEWLINE | newline_list NEWLINE ;linebreak : newline_list | /* empty */ ;separator_op : '&' | ';' ;separator : separator_op linebreak | newline_list ;sequential_sep : ';' linebreak | newline_list ;
%token WORD%token ASSIGNMENT_WORD%token NAME%token NEWLINE%token IO_NUMBER
%token AND_IF OR_IF DSEMI/* '&&' '||' ';;' */
%token DLESS DGREAT LESSAND GREATAND LESSGREAT DLESSDASH/* '<<' '>>' '<&' '>&' '<>' '<<-' */
%token CLOBBER/* '>|' */
/* The following are the reserved words. */
%token If Then Else Elif Fi Do Done/* 'if' 'then' 'else' 'elif' 'fi' 'do' 'done' */
%token Case Esac While Until For/* 'case' 'esac' 'while' 'until' 'for' */
/* These are reserved words, not operator tokens, and are recognized when reserved words are recognized. */
%token Lbrace Rbrace Bang/* '{' '}' '!' */
%token In/* 'in' */
Helper utilities
Helper utilities – various small external programs that are helpful when working with shell scripts or the command line
Called from shell (scripts or command line) Somehow transforms input into output, based on
the parameters
Helper utilities
cat - concatenate files and print on the standard output
Syntax: cat [file1] [file2] … [fileN]
girtsf@linux etc $ cat gentoo-release shells Gentoo Base System version 1.4.16# /etc/shells: valid login shells# $Header: /home/cvsroot/gentoo-src/rc-scripts/etc/shells,v 1.5
2003/07/15 20:36:32 azarah Exp $/bin/sh/bin/bash/bin/tcsh/bin/csh/bin/esh/bin/ksh/bin/zsh/bin/sash
Helper utilities
echo – displays a line of text Besides the program /bin/echo, also usually
built in the shell (takes precedence) Syntax: echo [STRING]
$ echo quick brown fox
quick brown fox
Can be used to display environment variables$ echo $HOME
/home/girtsf
Helper utilities
wc - print the number of newlines, words, and bytes in files wc [options] [file1] [file2] … [fileN]
By default, newlines, words and byte counts are displayed
Options -c : print only byte count -w : print only word count -l : print only line count
Helper utilities
Example use of wc:$ wc /etc/passwd
50 76 2257 /etc/passwd
$ wc -l /etc/passwd
50 /etc/passwd
lines words bytes
lines only
Helper utilities
grep - print lines matching a pattern grep PATTERN [file1] [file2] … [fileN]
The lines that contain PATTERN are printed to the standard output
If no files are specified, input is taken from the standard input (more later)
Advanced versions of grep allow using regular expressions in PATTERN
Helper utilities
File “testfile” contains the following lines:$ cat testfile
the quick brown
fox jumped over
the lazy dog
We search for “the”:$ grep the testfile
the quick brown
the lazy dog
Only lines containing the substring “the” are printed
Helper utilities
Some useful parameters for grep: -i : ignore case (“the” finds “the”, “The”, “THE”,…) -l : output only filenames that match, not the contents -B <n> : output also n lines before the matching line -A <n>: output also n lines after the matching line
See the man page (“man grep”) for all parameters
Helper utilities
tee - read from standard input and write to standard output and files Syntax: tee [File1] [File2] .. [FileN] Example of tee taking user’s input from terminal and writing to 3 files:
girtsf@linux tmp $ tee a b csome string^Dsome stringgirtsf@linux tmp $ cat asome stringgirtsf@linux tmp $ cat bsome stringgirtsf@linux tmp $ cat csome string
In red – my input, ending with Control-D, which is the EOF (End of File) character.
This input is read as standard input by tee.
Helper utilities
Any program can be used as a helper program More examples later
Connecting utilities with shell scripting
Standard I/O I/O redirection to/from file I/O redirection using a pipe Command substitution
Standard I/O
Every process, when run, has 3 already open data streams (file descriptors): Standard input Standard output Standard error
Standard I/O
When run interactively (from command line), these streams are attached to the terminal they are running from Standard input is attached to user’s keyboard input Standard output is attached to user’s terminal output Standard error, similarly to output, is attached to
user’s terminal output Usually referred to as stdin, stdout, stderr
Standard output & error
“ls” command does not use stdin, but uses stdout, stderr The second line is the stdout from “ls” command:
$ ls -l /etc/passwd
-rw-r--r-- 1 root root 2257 Oct 22 13:35 /etc/passwd
The second line is from stderr from “ls” command:$ ls -l /etc/asdfasdf
ls: /etc/asdfasdf: No such file or directory
Both stdout and stderr simultaneously:$ ls -l /etc/passwd /etc/asdfasdf
ls: /etc/asdfasdf: No such file or directory
-rw-r--r-- 1 root root 2257 Oct 22 13:35 /etc/passwd
I/O Redirection to/from file
By default, the 3 streams are attached to terminal This can be overridden when executing the
command and is called “redirection” “>” specifies that stdout is redirected to a file “<“ specifies that stdin is taken from a file “2>” specifies that stderr is redirected to a file “&>” specifies that both stdout and stderr are
redirected to the same file
I/O Redirection to/from file
Syntax: <cmd> [ > <file1>] [ < <file2> ] [ 2> <file3> ]
For redirections that are specified, the respective stream will be attached to the specified file None, one, two or all three types can be specified
If output file exists: > - replace the file >> - append to the file
I/O Redirection to file
Example of stdout redirection to file$ ls -l /lib/ > direktorijas_saraksts
$ cat direktorijas_saraksts
total 4035
-rwxr-xr-x 1 root root 7488 Oct 6 12:33 cpp
drwxr-xr-x 13 root root 1024 Oct 25 15:57 dev-state
drwxr-xr-x 2 root root 1024 Jun 28 09:53 evms
drwxr-xr-x 2 root root 2048 Aug 23 15:25 iptables
...
I/O Redirection to file
Example of stdout redirection to file$ ls -l /asdf > direktorijas_saraksts
ls: /asdf: No such file or directory
$ cat direktorijas_saraksts
The file is empty, as no output was sent to stdout The error message was send to stderr which was
attached to user’s terminal
I/O Redirection to file
Example of stderr redirection to file$ ls -l /asdfasdf 2> errlog
$ cat errlog
ls: /asdfasdf: No such file or directory
Now stderr was redirected to file and file containes the error message
I/O Redirection to file
Example of stdout, stderr redirection to file$ ls -l /asdfasdf /lib 2>errlog >sar$ cat errlog ls: /asdfasdf: No such file or directory$ cat sar/lib:total 4035-rwxr-xr-x 1 root root 7488 Oct 6 12:33 cppdrwxr-xr-x 13 root root 1024 Oct 25 15:57 dev-statedrwxr-xr-x 2 root root 1024 Jun 28 09:53 evmsdrwxr-xr-x 2 root root 2048 Aug 23 15:25 iptables...
I/O Redirection from file
Example of stdin redirection First, we create file “a” with the following content
the quick brown foxjumped over a quick brown fox
Use wc (word count) by not supplying the file name, but redirecting the standard input
$ wc < a 2 10 50
I/O Redirection with pipes
Task: given a file, output the total number of words in those lines, that contain substring “the”
Example input:$ cat testfile
the quick brown
fox jumped over
the lazy dog
Lines 1 and 3 match, total number of words = 6
I/O Redirection with pipes
Solution with redirection to files: First find the lines, save them into a temp file Then use the wc utility to count the number of words
$ grep the testfile > tmpfile
$ wc –w < tmpfile
6
I/O Redirection with pipes
A temporary file was used to redirect the standard output of grep to file
The standard input to wc was taken from the temporary file
An easier way – connect the standard output of one program to standard input of another one directly by using a pipe
I/O Redirection with pipes
Syntax: program1 | program2 (|- the pipe symbol) A mechanism for interprocess communication, provided by
the special filesystem pipefs The data is handled in FIFO order The pipe has no name; it is created for one use, and both ends must be
inherited from the same process which created the pipe No temporary files!
$ grep the testfile | wc -w
6
Another example: $ ls -1 | wc –l
Command substitution By using backticks, a sub-command is executed first
The sub-command is substituted (on the command line) by its standard output The output can be stored in a variable
A backtick or backquote: ` Usually the same key as for ~
Alternative syntax: $() – allows for nesting Example:usr@nix:/$ cd `echo $HOME` usr@nix:/$ H=`echo $HOME`
usr@nix:~$ usr@nix:/$ cd $H
Substituted with the value of $HOME
Helper utilities
We will examine the following utilities: cut sort uniq awk sed
cut
cut - remove sections from each line of files Extract sections from a text-file by selecting columns
Syntax: cut [OPTION]... [FILE]... Options:
-d DELIM : use DELIM instead of TAB character -f LIST : output only these fields (delimited by DELIM) -c LIST : output only these characters
See man page for more options
cut
Example – output second word on each line: Delimiter: the space character Field: 2
$ cat athe quick brown foxjumped over a quick brown fox$ cut -f 2 -d ' ' aquickover
Example – extract certain fields from the passwd file:$ cut -d':' -f1,3-4 /etc/passwd --output-delimiter=$'\t'
cut
Example – output characters 1-3, 5, 7-end Use –c to choose the needed characters
$ cat a
the quick brown fox
jumped over a quick brown fox
$ cut -c 1-3,5,7- a
theqick brown fox
jume over a quick brown fox
sort
sort - sort lines of text files sort [OPTION]... [FILE]...
Writes sorted concatenation of all FILE(s) to stdout Interesting options:
-r : reverse -n : compare according to string numerical value
See man page for more options
sort
sort - sort text file reversed
$ cat a fishdoganimalbird
$ sort -r afishdogbirdanimal
sort
Sort numeric values as text
$ cat a5412 this line should go last998 this line should go second50 this line should go first999 this line should go third
$ sort a50 this line should go first5412 this line should go last998 this line should go second999 this line should go third
sort
Sort numeric values as numbers
$ cat a5412 this line should go last998 this line should go second50 this line should go first999 this line should go third
$ sort -n a50 this line should go first998 this line should go second999 this line should go third5412 this line should go last
uniq
uniq - remove duplicate lines from a sorted file uniq [OPTION]... [INPUT [OUTPUT]]
Discards all but one of successive identical lines from INPUT (or stdin), writing to OUTPUT (or stdout)
Can be used together with sort, to get file without duplicate lines
uniq
Just sorted:
$ cat a | sortbirdbirddogdogfishfishfly
sort | uniq:
$ cat a | sort | uniqbirddogfishfly
awk
gawk (GNU awk) - pattern scanning and text processing language Gawk is the GNU Project's implementation of the AWK
programming language. It conforms to the definition of the language in the POSIX 1003.2 Command Language And Utilities Standard. This version in turn is based on the description in The AWK Programming Language, by Aho, Kernighan, and Weinberger, with the additional features found in the System V Release 4 version of UNIX awk.
Originates from 1970s
awk
Complete language interpreter Variables User defined functions …
Useful for small one-liners For processing text files
A file is treated as a sequence of records (lines by default)
An AWK program is a series of pattern-action pairs A record (line) is scanned for each pattern in the program
awk
Task: sum all the numbers in the file$ cat a
1
2
3
4
5
$ cat a | awk '{ sum += $1 } END { print sum }'
15
executed on every line executed at the end
first field
awk
Sum the 2nd field (separated by colons) of those lines that contain the letter “a”
$ cat azzz:1:azzz:2:bzzz:3:bzzz:4:bzzz:5:a
$ cat a | awk -F ':' '{ if(/a/) sum += $2; } END { print sum }'
6
field delimiter
sed
sed – stream editor (from 1970s) A stream editor is used to perform basic text parsing
and transformation on an input stream (a file or an input from a pipeline) While in some ways similar to an editor which permits
scripted edits (such as ed), sed works by making only one pass over the input(s), and is consequently more efficient
Simpler than awk, smaller feature set (20+ commands)
sed
Replace some substring with another
$ cat a
bird barks
mouse runs
$ sed 's/barks/flies/' < a
bird flies
mouse runs
Regular expression
The substitute command
sed
Replace some characters with others Replacing ‘b’ with ‘B’, ‘i’ with ‘I’ etc.
$ cat a
bird barks
mouse runs
$ cat a | sed 'y/bis/BIS/'
BIrd BarkS
mouSe runS
The transform command
Advanced example (1)
Calculate the total bytes transferred by Apache First, take only successful lines (containing error code 200) Sum up byte field
The log file format:
159.148.123.123 - - [28/Oct/2004:18:11:36 +0300] "GET /somefolder/file.php HTTP/1.1" 200 127602 "-" "Opera/7.54 (X11; Linux i686; U) [en]"
Advanced example (1)
$ sudo cat /var/log/apache2/access.log | grep ' 200 ' | awk '{ bytes += $10 } END { print bytes }'
1105653994 Cat file Grep for " 200 " Sum up 10th column, output the result at the end
Alternatively:$ sudo cut -f9-10 -d' ' /var/log/apache2/access.log
| awk '{ if($1 == 200) bytes += $2 } END { print bytes }'
1105653994
Advanced example (2)
Calculate the number of hits per remote host in Apache log file Output the most active hosts first
159.148.123.123 - - [28/Oct/2004:18:11:36 +0300] "GET /somefolder/file.php HTTP/1.1" 200 127602 "-" "Opera/7.54 (X11; Linux i686; U) [en]"
Advanced example (2)
$ cat access.log | cut -d ' ' -f 1 | sort | uniq -c | sort –n -r
First, cut out the host part (1st field) and sort the output Remove the duplicate lines
Prefix the remaining lines by the number of occurrences (frequency counts) Sort the output again: in the reverse-frequency order
The final output:348698 159.148.111.222123485 159.148.48.54 12313 80.123.123.4 ... ...
UNIX for Poets(by Kenneth Church)
Uzdevums: doto teksta failu (piem., Raiņa korpusu) sadalīt vārdlietojumos; izveidot sakārtotu vārdformu biežumsarakstu
tr 'A-ZĀČĒĢĪĶĻŅŖŠŪŽ' 'a-zāčēģīķļņŗšūž' < Rainis.txt| tr -sc 'a-zāčēģīķļņŗšūž' '\n'| sort| uniq -c| sort -n -r > Rainis_freq.txt
1613 un 418 tik 323 lai 204 nau 524 kā 374 ar 312 vai ... 462 no 362 tā 306 uz 124 sirds 445 kas 361 vēl 291 to ... 430 ir 359 tu 285 man 95 saule 427 es 349 ko ... ...
Helper utilities
Some more utilities that can be useful head, tail - output the first/last part of files basename - strip directory and suffix from filenames bc - an arbitrary precision calculator sleep – sleep specified number of seconds tr – translate or delete characters true, false – always return success/error code
Read the man pages
Tips for working in a shell
The UP arrow – repeats the previous command
history – internal bash command that shows the command history
CTRL-R and a few chars recalls last command that contains these chars: (reverse-i-search)`re': grep text file*
Use script to make a typescript of terminal session
Use TAB for the built-in auto-completion
CTRL+A – moves the cursor the start of the line CTRL+E – moves the cursor to the end of the line
CTRL+C – sends the kill signal (SIGINT) to the currently running (foreground) process
The ABCs of Unix
A is for awk, which runs like a snail B is for biff, which reads all your mail C is for cc, as hackers recall D is for dd, the command that does all E is for emacs, which rebinds your keys F is for fsck, which rebuilds your trees G is for grep, a clever detective H is for halt, which may seem defective I is for indent, which rarely amuses J is for join, which nobody uses K is for kill, which makes you the boss L is for lex, which is missing from DOS M is for more, from which less was begot
N is for nice, which really is not O is for od, which prints out things nice P is for passwd, which reads in strings twice Q is for quota, a Berkeley-type fable R is for ranlib, for sorting a table S is for spell, which attempts to belittle T is for true, which does very little U is for uniq, which is used after sort V is for vi, which is hard to abort W is for whoami, which tells you your name X is, well, X, of dubious fame Y is for yes, which makes an impression, and Z is for zcat, which handles compression
Another UNIX command reference
Use the man pages for further details
Intercative shell coniguration files
Shell scripts as files
Everything that can be called from the command line can also be called from a shell script
Shell Script is a series of commands written in a plain text file Shell is a command-line interpreter (not a compiler)
A shell script in UNIX is like a batch file in MS-DOS, but, in general, it is more flexible and powerful
Running a shell script
As a parameter to the shell interpreterbash some_script.sh
Specifying the interpreter on first lineFirst line: #!/bin/bash
Can be omitted if the script consists only of a set of generic system commands, using no internal shell directives
Make it executable: chmod a+x some_script.shExecute: ./some_script.sh
Basics
Interpreted line by line The same effect when entering the lines one
by one in interactive shell
Sample shell script
#!/bin/bash# comment lineecho "what a fine day: "date
Output, when called by “./test.sh”:what a fine day: Thu Oct 28 23:37:39 EEST 2004
Interpreter to be used
Regular commands to execute
Variables
Sample “hello world” with variables:#!/bin/bash STR="Hello World!"echo $STR
When assigning, $ is not used When getting the contents, use $
No data types – string, number, character, all the same Essentially, bash variables are character strings, but, depending on
context, bash permits arithmetic operations and comparisons on variables
More variables
#!/bin/bash
DATE=`date +%Y%m%d`
WHAT='/home/girtsf'
DEST="/backups/$DATE.tgz"
tar cvzf $DEST $WHAT
Results in calling:tar cvzf /backups/20041028.tgz /home/girtsf
Conditionals
if TEST-COMMANDS; then CONSEQUENT-COMMANDS; fi
If TEST-COMMAND's return status is zero, the CONSEQUENT-COMMANDS list is executed
#!/bin/bashT1="foo"T2="bar"if [ "$T1" = "$T2" ]then
echo expression evaluated as trueelse
echo expression evaluated as falsefi
Command line arguments
Automatically defined variables $0 – contains shell script name $1 – contains first argument $2 – contains second argument … $* - contains all arguments as a string
Command line arguments
$ cat printer.sh:#!/bin/sh# A script to print a file#if cat $1then echo -e "\n\nFile $1 found and printed"fi
$ ./printer.sh file.txt
Returns an error code
0 = successful
If 0, executes then
Comparisons
Either "test <expression>" or "[ <expression> ]" if test $1 -gt 0 if [ $1 -gt 0 ]
Numeric comparisons: -eq, -ne: equal / not equal -lt, -le, -gt, -ge : less than, less than or equal, greater
than, greater than or equal
Comparisons
String comparisons string1 = string2 string1 is equal to string2 string1 != string2 string1 is not equal to string2
string1 string1 is NOT NULL or not defined -n string1 string1 is NOT NULL -z string1 string1 is NULL (zero length)
File tests
-e file file exists -s file file is not zero size -f file file is a regular file (not a directory or device) -d file file is a directory -w file file has write permission for the user running the test -r file file has read permission -x file file has execute permission -L file file is a symbolic link ...
Logical Operators
! expression Logical NOT expression1 -a expression2 Logical AND expression1 -o expression2 Logical OR
Yet another example#!/bin/sh# Script to test if..elif...else#if [ $1 -gt 0 ]; then echo "$1 is positive"elif [ $1 -lt 0 ]then echo "$1 is negative"elif [ $1 -eq 0 ]then echo "$1 is zero"else echo "Opps! $1 is not a number, give me a number"fi
Arithmetic expansion
Arithmetic expansion allows the evaluation of an arithmetic expression and the substitution of the result Translating a string into a numerical expression
The syntax for arithmetic expansion is: $((expression))A=5B=4C=$(($A*$B))echo $C
Alternatively: let C=A*B / let "C = A * B"
Loops: for
for { variable name } in { list }do
iterate through the items in the list and for each item repeat all statements in the do block
done
for i in 1 2 3 4 5do echo "Welcome $i times"done
Loops: for
You can use for together with file name expansion (globbing) to perform the same action for several files
#!/bin/shfor x in *txtdocat $x
done
Loops: for
for (( expr1; expr2; expr3 )) do
repeat while expr2 is truedone
for (( i = 0; i <= 5; i++ ))do echo "Welcome $i times"done
Loops: while
while [ condition ]do
command1command2command3...
done
Many more features
See man page
Linux Shell Scripting Tutorial: A Beginner's handbook: http://www.freeos.com/guides/lsst/
Advanced Bash-Scripting Guide http://www.tldp.org/LDP/abs/html/index.html
Word guessing game
Source: http://www.ltn.lv/~guntis/unix/mini.txt
+------ |/ | | o | O | / |
MATER_ALJuusu mineejums: i
Main partizveleties_vardustripasgaj=0while true;do
zimet_karatavas $gaj
echo $vecho -n "Juusu mineejums: "read ievgajiens $iev
if [[ $v == $vards ]]; thenuzvara; exit
fi
if [[ $gaj -eq 10 ]]; thenzaude; exit
fi
done;
Get a random wordizveleties_vardu(){
local sk r
if [[ -e /usr/share/dict/words ]];thenecho Nemu vienu nejausu vardu no vardnicassk=`cat /usr/share/dict/words | wc -l`r=$(($RANDOM % $sk + 1))vards=`tail -n $r /usr/share/dict/words | head -n 1| tr a-z A-Z`elseecho Vardnica nav atrasta, nemu nokluseto varduvards="KARATAVAS"fisleep 1
}
Convert letters to underscores
stripas(){
local ii=${#vards} # String lengthv= # Empty stringwhile [[ $i > 0 ]];do
i=$(($i-1))v=${v}_ # Append to string
done}
Comparison partgajiens() {
b=${iev:0:1} # Get first charl=${#vards}i=0ir=0while [[ $i < $l ]]; do
t=${vards:$i:1} # Get char at i-th position
if [[ $t == $b ]]; thenv2=${v2}$bir=$(($ir+1))
elsev2=${v2}${v:$i:1}
fii=$(($i+1))
doneif [[ $ir -eq 0 ]]; then
gaj=$(($gaj+1))return
fiv=$v2
}
'Bash' bug ("Shellshock" bug)
Wade Mealing 2014-09-14 22:24:57 EDT
A flaw was found in the bash functionality that evaluates specially formatted environment variables passed to it from another environment. An attacker could use this feature to override or bypass restrictions to the environment to execute shell commands before restrictions have been applied. Certain services and applications allow remote unauthenticated attackers to provide environment variables, allowing them to exploit this issue.
Acknowledgements:Red Hat would like to thank Stephane Chazelas for reporting this issue.
env x='() { :;}; echo vulnerable' bash -c 'echo this is a test'