Shell Programming
What is a shell program? After logging onto the system a prompt for input appears which is generated by a Command String Interpreter program called the shell. The shell: interprets the input, takes appropriate action, and Finally prompts for more input. The shell can be used either interactively - enter commands at the command prompt, or as an interpreter to execute a shell script Note: Shell scripts are dynamically interpreted, NOT compiled.
Common Shells C-Shell - csh The default on teaching systems Good for interactive systems Inferior programmable features Bourne Shell - bsh or sh - also restricted shell - bsh Sophisticated pattern matching and file name substitution Korn Shell Backwards compatible with Bourne Shell Regular expression substitution emacs editing mode Born Again Shell - BASH Thomas C-Shell - tcsh Based on C-Shell Additional ability to use emacs to edit the command line Word completion & spelling correction
Shell Scripts For example, a simple C Shell Script in file name list.csh #! /bin/csh ls -al | more In the above script the first line signals that the file list.csh contains a C Shell Script (csh). To execute the above script we can either execute it with csh: csh list.csh or you can execute it directly from the command line but you must first change the permission of the file list.csh using the chmod command so that it has execute privileges (chmod +x list.csh).
General Shell Scripts If the first line is just a # then the script is interpreted by a C shell: # This is a sample C shell script.· echo -n the date today isdate # output today’s date. If the first line is in the form #! PathName, then the executable program PathName is used to interpret the script. · #! /bin/ksh· # This is a sample Korn shell.· echo -n the date today isdate # output today’s date. · If neither of the above rules apply, then the script is interpreted by a Bourne shell. echo -n the date today is· date # output today’s date. # This would be interpreted by the Bourne shell.
C Shell Commands Variables The C Shell offers a command "Set" to assign a value to a variable. For example: set myname= Fred set myname = "Fred Bloggs“ set age=20 A $ sign operator is used to recall the variable values. echo $myname will display Fred Bloggs on the screen A @ sign can be used to assign the integer constant values. @myage=20 @age1=10 @age2=20 @age=$age1+$age2 echo $age
List variables set programming_languages= (C Java) echo $programming _languages C Java set files=*.* set colors=(red blue green) echo $colors[2] blue
Input/Output Commands Echo command displays information on the screen. For example: echo I am here will display "I am here" on the screen. $< command reads data from the keyboard set myname = $< waits for data ( name) EXAMPLE write a script that reads name from the keyboard and display on the screen. #!/bin/csh echo $myname
Control Structures The C Shell offers three loop structures foreach, while and repeat and 3 branching statements if, switch and goto. foreach .. end foreach variable name(list) commands end
EXAMPLE foreach color (red yellow green) set files = *.csh echo one color is $color end set files = *.csh foreach filename=($files) echo $filename cat $filename while .. End while (expression) commands EXAMPLE set count=1 while ($count <= 2) echo $count @ count++
repeat repeat (expression) command repeat 3 echo hello
if Statement The if statement has the following formats: 1) if (exp) command 2) if (exp) then commands endif 3) If (exp) then commands else endif
Example set myname = ali If ($myname == ali) then echo "my name is ali" else echo "my name is not ali" endif
switch .. case .. endsw switch (expr) case pattern1: list Breaksw ... default: defaultlist endsw
Example echo -n "Do you want to delete test.c?“ set answer = $< If ($answer == "yes") then rm test.c else If ($answer =~ a*) then echo -n "Do you really mean that?" set answer = $< If ($answer == "yes") then echo "rm *.*" endif
Arithmetic Expressions ! logical negation * / % multiplication, division, remainder + - || && etc., Example: set num1=5*6 set num2=6 If (num1>20 && num2==6) then echo $num1 endif @ num1=5*6 if (num1>20 && num2==6) then echo $num1
Aliases alias dir ‘ls -a’ unalias dir Useful Aliases cd.. cd .. rm rm -i (force interactive mode) h history
Goto goto name ... name:
Example - Menu #!/bin/tcsh echo menu test program set stop = 0 while ($stop == 0) echo 1 : date and time echo 2 : who is logged on echo 3 : exit echo -n 'your choice ' set reply = $< switch ($reply) case 1 : date breaksw case 2 : who case 3 : set stop=1 default: echo illegal choice breaksw endsw end
Process Control in the C-Shell Commands can be invoked in sequence using ; vi file.f ; job2 -? ; job3 Commands can be invoked in parallel using | ps aux | grep igor | awk “{print $2}” Commands can be collected into a group (sub-shell) using () (echo Status ; date ; who) > user_log Commands can be logically related using && or || pc -o myprog.myprog && myprog (invoke pc; if successful, run myprog) pc -c myprog.p || vi myprog.p (invoke pc; if unsuccessful, invoke vi)
Cont. Commands are loaded into the background using &matlab <input >& errors & warning if background job running at logout Can keep background job running after logout: nohup matlab <input >& errors & Next login: ps aux | grep your_username if process details are printed, process still alive!
Job control commands: jobs # list jobs ^Z # stops current foreground job· · ^C # abandons current foreground job bg # restarts highest stopped job in # background mode· · bg %2 # restarts job [2] in background mode fg %ls # restarts job ls in foreground mode kill %1 # terminate job· stop %1 # stop job
Example % jobs % ls -R / >& /dev/null ...^Z Stopped % jobs –l [1] + 8646 Stopped ls -R / >& /dev/null % bg[1] ls -R / >& /dev/null & % jobs[1] Running ls -R / >& /dev/null % fg %ls ls -R / >& /dev/null ^Z [1] + Stopped ls -R / >& /dev/null % find / -name '*.*' -print >& /dev/null
% jobs [1] - Stopped ls -R / >& /dev/null [2] + Stopped find / -name *.* -print >& /dev/null % bg %2 [2] find / -name *.* -print >& /dev/null & % bg %1 [1] ls -R / >& /dev/null & [1] Running ls -R / >& /dev/null [2] + Running find / -name *.* -print >& /dev/null % kill %fi [2] Terminated find / -name *.* -print >& /dev/nul l% stop %1 [1] + Stopped (signal) ls -R / >& /dev/null % find / -name '*.*' -print >& /dev/null & [2] 8651 [2] - Running find / -name *.* -print >& /dev/null % kill %1 [1] Terminated ls -R / >& /dev/null % fg %2 find / -name *.* -print >& /dev/null ^C