130 likes | 272 Views
Shell Programming – Extra Slides. Counting the number of lines in a file. #!/bin/sh #countLines1 filename=$1 #Should check if arguments are given count=0 while read aline do count=`expr $count + 1` done < $filename echo "$filename has $count lines“ From the command line:
E N D
Counting the number of lines in a file #!/bin/sh #countLines1 filename=$1 #Should check if arguments are given count=0 while read aline do count=`expr $count + 1` done < $filename echo "$filename has $count lines“ From the command line: $wc –l data.txt 11 data.txt $countLines1 data.txt Data.txt has 0 lines
Counting the number of lines in a file #!/bin/sh #countLines2 filename=$1 #Should check if arguments are given count=0 Cat $filename | while read aline do count=`expr $count + 1` done echo "$filename has $count lines“ From the command line: $wc –l data.txt 11 data.txt $countLines2 data.txt Data.txt has 0 lines WHY? Subshell execution takes place if input is piped into a for, while, until, if or case command or if the output is piped out.
Counting the number of lines in a fileSolution #!/bin/sh #countLines3 filename=$1 #Should check if arguments are given count=0 exec < $filename #any commands that will read from stand in # will read from $filename while read aline do count=`expr $count + 1` done echo "$filename has $count lines“ From the command line: $countLines3 data.txt Data.txt has 11 lines exec < /dev/tty --- Reassign the standard input back to terminal
trap • The pressing of DELETE key at the terminal, when a program is in execution, sends a signal to the executing program. • Using the trap command, the program can specify the action to be taken on receiving the signal. • Usage: trap commands signals, where commands are the actions to be taken on receiving the signals. • Some Commonly used signal numbers • 0 Exit from Shell • 1 Hangup • 2 Interrupt (eg: Delete key) • 15 Software termination (sent by kill, for example)
Example Example 1: #!/bin/sh i=1 JUNK=junkfile trap ‘rm $JUNK$$;exit’ 2 while [ $i -le 100 ] Do # remove the file when interrupt is received echo $i >> $JUNK$$ i=`expr $i + 1` done
Examples Example 2: trap 'echo Caught SIGINT - exiting; exit' 2 X=0 while : #loop forever do echo "X=$X" X=`expr ${X} + 1` sleep 1 Done Example 3 #!/bin/sh trap 'echo `pwd` $$ >>./errdir' 2 3 15 while (true) do echo 'Hi' done
Example #!/bin/sh #What does this program do? trap 'increment' 2 increment() { echo "Caught SIGINT ..." X=`expr ${X} + 500` if [ "${X}" -gt "2000" ] then echo "Okay, I'll quit ..." exit 1 fi } ### main script X=0 while : do echo "X=$X" X=`expr ${X} + 1` sleep 1 done
Input and Output Redirection • We know that Unix shell allows us to redirect the input and output of programs using redirection (> and <) and piping(|). • When the Unix kernel starts any process, for example, grep, ls and so on, it sets up several places, called open files, for that process t read from and write to. Each of these files is given a number to identify with, called a file descriptor. • A file descriptor (also known as a file handle) is a non-negative digit that points at a file. • The file descriptors for stdin, stdout, and stderr are 0, 1, and 2, respectively. Any of these may be redirected to a file or to each other. • In other words, it is quite possible to send the output from stdin and stderr to the same file. This is quite useful when a user would rather check a script's results after it has completed processing. • By default, the file that is opened for stdin, stdout and sterr is /dev/tty (your terminal). • But, when the shell starts a process, you can tell the shell what file to connect to any of those file descriptors. • For example in the following command, grep aPattern somefile > output, the file descriptor 1 is connected to the file, output.
More On I/O • What if you want to send the standard out to screen and capture the standard error in a pipe or a file? • It is easy to redirect any file descriptor to any file. Eg: command 2>errorFile command 2> file – redirects the standard error from any command cd JUNK 2>>out #the directory JUNK does not exist cat out sh: JUNK: not found.
More On I/O • What if you want to send the standard out to screen and capture the standard error in a pipe or a file? • It is easy to redirect any file descriptor to any file. Eg: command 2>errorFile command 2> file – redirects the standard error from any command cd JUNK 2>>out #the directory JUNK does not exist cat out sh: JUNK: not found. • Let us take a look at a few cases: • Sending both standard output and errors to the pipe or backquotes. command 2>&1 |… or var=`command 2>&1` This means that send standard error (with file descriptor 2) to the same place standard output is going (down the pipe or backquotes)
More On I/O • Sending stderr go down a pipe and stdout to the screen. command 2>&1 1>&2|… Will Not Work We should use file descriptors 3 to 9,as holding places, to accomplish this. command 3>&2 2>&1 1>&3 |… or var=` command 3>&2 2>&1 1>&3`
More On I/O Example: For the following grep command, assume that afile contains one matching line for “unix” and bfile does not exist. var=`grep “unix” afile bfile` echo $var #What is the output? var=`grep “unix” afile bfile 3>&2` echo $var #What is the output? var=`grep “unix” afile bfile 3>&2 2>&1` echo $var #What is the output? var=`grep “unix” afile bfile 3>&2 2>&1 1>&3` echo $var #What is the output?