Basic scripting Interpreted Languages vs Compiled Languages Compiled languages good for medium and largescale complicated number crunching programs Fortran Ada Pascal C C The programs are translated from their original source code into object code which is then executed directl ID: 171493
Download Presentation The PPT/PDF document "Shell Scripting" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1Slide2
Shell Scripting
Basic scriptingSlide3
Interpreted Languages
vs
Compiled Languages
Compiled languages: good for medium and large-scale complicated number crunching programs
Fortran,
Ada
, Pascal, C, C++
The programs are translated from their original source code into object code which is then executed directly by the computer's hardware.
they're
efficient
Interpreted languages are usually interpreted and good for smaller scale problems
A regular compiled program, the interpreter, reads the program, translates it into an internal form, and then executes the program (
ie
.,
Matlab
)Slide4
What is a shell script?
It is a program that is written using shell commands (the same things you type to do things in the shell).
Shell scripts are used most often for combining existing programs to accomplish some small, specific job.
Once you've figured out how to get the job done, you can bundle up the commands into a separate program, or
script
, which you can then run directly. Slide5
Shell scripts are strictly interpreted.
The philosophy of shell scripting is to
develop
a tool with the shell
then
write the final, efficient, implementation of the tool in C (or other high level language).
The
second step is typically skipped.Slide6
Why use shell scripts?
Repeatability
why bother retyping a series of common commands?
Portability
POSIX standard – formal standard describing a portable operating environment
IEEE Std 1003.2 current POSIX standard
SimplicitySlide7
Simple example
%more 0.5/run.csh
mkdir
0.5_3
tomoDD2.pwave
tomoDD.3.inp
mv
red* 0.5_3
cp
tomo
* 0.5_3
mv
Vp
* 0.5_3
mkdir
0.5_20
tomoDD2.pwave
tomoDD.20.inp
mv
red* 0.5_20
cp
tomo
* 0.5_20
mv
Vp
* 0.5_20
#This csh script simply runs a series of tomographic inversions using different parameter setups.
#By setting up the runs in a script and having the script automatically run the code and then move the output files to specially name directories, I can run numerous jobs overnight instead of watching each job take 1.5 hours, copying the files, and starting a new job.Slide8
Simple example
%more 0.5/run.csh
mkdir
0.5_3
tomoDD2.pwave
tomoDD.3.inp
mv
red* 0.5_3
cp
tomo
* 0.5_3
mv
Vp
* 0.5_3
mkdir
0.5_20
tomoDD2.pwave
tomoDD.20.inp
mv
red* 0.5_20
cp
tomo
* 0.5_20
mv
Vp
* 0.5_20
#When we run the script, it runs the commands in the file – so it runs the program tomoDD2, and moves the output files to specially named directories.
#It then does it again with a different input data set.Slide9
Standard example
Create a file (typically with an editor), make it executable, run it.
%
vim
hello.sh
#!/bin/bash
echo 'Hello world.’
a=`echo "Hello world." | wc`
echo "This phrase contains $a lines, words and characters"
%
chmod
ug+x
hello.sh
%
./
hello.sh
run your script from the command line
Hello world.
This phrase contains 1 2 13 lines, words and charactersSlide10
New Unix construct
Command substitution –
Invoked by using the
back
or
grave
(French) quotes (actually accent, `).
a=`echo ”hello world." |
wc
`
What is this?Slide11
Command substitution tells the shell to run what is inside the back quotes and substitute the output of that command for what is inside the quotes.Slide12
So the shell runs the command
echo hello world. |
wc
%echo hello world. |
wc
1 2 13
takes the output
(the “1 2 13” above)
, substitutes it for what is in the back quotes
(
echo ”hello world.
)
, and sets the shell variable equal to it
a=`echo ”hello world." |
wc
`
does this (is as if you typed)
a=‘1 2 13’Slide13
The #! First Line
(aka shebang)
The first line tells the system what language (shell) to use for command interpretation
It is a very specific format
#!/bin/
sh
or
#!/bin/
csh
–
f
(the –
f
is optional –
Fast start. Reads
neither the
.cshrc file nor the .login file (if a login shell) upon startup.)Slide14
If you want your shell script to use the same shell as the parent process you don’t need to declare the shell with the shebang at the beginning.
BUT
You can’t put a comment (indicated by #) in the first line, so the first line has to be one of
#!
or
command (not a comment)Slide15
Scripting Etiquette
Most scripts are read by a person and by a computer. Don’t ignore the person using or revising your script.
Use comments to tell your readers what they need to know. The # denotes a comment in bash and csh
Use indentation to mark the various levels of program control (loops, if-then-else blocks)
Use meaningful names for variables and develop a convention for that helps readers identify their function
Avoid unnecessary complexity…keep it readableSlide16
Header
Adding a set of comments at the beginning that provides information on
Name of the script
How the script is called
What arguments the script expects
What does the script accomplish
Who wrote the script and when
When was it revised and howSlide17
#!/
usr/bin/sh
-f
#Script:
prepSacAVOdata.pl
#Usage: $script <
unixDir
> <
dataDirList
> <
staFile
> <
phaseFile
> <
eventFile
>#------------------------------------#Purpose: To prepare SAC AVO data for further processing# (1) generate event information file and add the event info (name, event location) to the SAC headers# (2) generate event phase file and add the phase info (time and weights) to the SAC headers#Original Author (prepSacData.pl: Wen-xuan(Wayne) Du Date: March 18, 2003; Modified: May 21, 2004##Last Modified by Heather DeShon Nov. 30, 2004# A) Reads AVO archive event format directly (hypo71): subroutines
rdevent and rdphase# B) Reads SAC KZDATA and KZTIME rather than NZDTTM, which is not set in AVO SAC data# C) stations in phase files but not in station list are reported in the warnings file
# D) set unique event ids in the order of the events starting from 0Slide18
if [$# != 5]
then
print "Usage:\
t\t$script
<
unixDir
> <
dataDirList
> <
staFile
> <
phaseFile
> <
eventFile
>\n";
print "<unixDir>:\tdirectory in the unix system where pick file is stored;\n"; print "<dataDirList>:\tlist of data directories under <unixDir>; 'dataDir.list';\n"; print "<staFile>:\tstation
file;\n"; print "<phaseFile>:\tphase info file for program 'ph2dt';\n"; print "<
eventFile
>:\
tevent info file (one line for one event);\n"; exit (-1);
fi
Do (at least simple) error checking of call and print some sort of message for error.Slide19
One of the things done in the error processing (in the
red box
) is the command “exit(-1)”.
if [ $# -ne 5 ]
then
. . .
exit (-1)
fi
This returns a message, a numeric “
return value” (in this case a -1) to the parent process.Slide20
Many programs return a value of 0 (zero) upon successful completion.
From the
ls
man page -
EXIT STATUS
0 All information was written successfully.
>0 An error occurred
.
So we can tell if it terminated successfully (but not what the error was if not).Slide21
Types of commands
Built-in commands
: commands that the shell itself executes.
Shell functions
: self-contained chunks of code, written in the shell language, that are invoked in the same way as a command
External commands
: commands that the shell runs by creating a separate processSlide22
Variables
a
variable
is used to store some piece of information (character, string, value)
the $ tells the shell to return the value of the specified variable
csh example
%
set
b
= “Hello world.”
%
set a = `echo $
b
| wc`
%
echo $a
1 2 13bash example$b=“Hello world.”$a=`echo $b | wc`$
echo $a1 2 13Slide23
the syntax for assigning variables is one of the most notable differences between bash and
csh
Bash cannot have spaces on either side of the equals sign.
csh
does not care
csh example
%
set
b
= “Hello world.”
%
set a = `echo $
b
| wc`
%echo $a1 2 13bash example$b
=“Hello world.”$a=`echo $b | wc`$echo $a
1 2 13Slide24
Constants
a
constant
is used to store some piece of information (character, string, value) that is not expected to change
in bash, variables are made constants by using the
readonly
command
bash example
$
x
=2
$
readonly
x
$
x=4bash: x: readonly variableSlide25
Quote syntax
‘…’: single quotes forces literal interpretation of everything within the quotes
Without the ‘’, variable
b
would be set to Hello in this example, and the shell would then try to run command
world.
csh example
%
set
b
=
‘
Hello world. $
’
%
echo $
bHello world. $bash example$
b=‘Hello world. $’$echo $a
Hello world. $Slide26
“…”: double quotes are used to explicitly group words/characters but escape characters, variables, and substitutions are still honored
csh example
%
set
b
=
“
Hello world. $
”
%
echo $
b
Illegal variable name.
bash example
$
b
=“Hello world. $”$
echo $aIllegal variable name.Slide27
In
csh/tcsh
, the variable
b
below would be set to
Hello
, and the shell would ignore the string
world
.
%
echo $0
tcsh
%
set
b
=hello world
% echo $
b
hello
What happens if you forget the quotes depends on the shell.Slide28
In
sh
/bash, the variable
b
below would be set to
Hello
, and the shell would try to run the command
world
.
$
b
='hello world'
$
echo $
b
hello world
$ b
=hello worldworld: not foundSlide29
Single vs. double quotes.
%
set a = A
%
echo $a
A
%
set
b
= 'letter $a'
%
echo $
b
letter $a
Shell did not expand variable
a
to its value. Treated literally ($a).% set
c = "letter $a"% echo $
c
letter A
Shell expanded variable a to its value,
A,
and passed value on.Slide30
`…`:
backquotes
are used for command substitution
the variable is set to the final output of all commands within the back single quotes
csh example
%
set
b
=
‘Hello world.’
%
set a =
`
echo $
b
| wc
`%echo $a1 2 13bash example$b
=‘Hello world.’$a=`echo $b | wc
`
$
echo $a1 2 13Slide31
Reading command line arguments
You can send your script input from the command line just like you do with built-in commands
#!/bin/bash –f
echo "Hello. My name is $HOST. What is yours?”
where $1 is the first argument following the command
echo "Nice to meet you $1.”
$
./
hello.sh
Heather
Hello. My name is
sailfish.ceri.memphis.edu
. What is yours?
Nice to meet you Heather.Slide32
think of the command line as an array starting with
0
%command arg1 arg2 arg3 arg4 … arg10
array[
0
]=command
array[1]=arg1
array[2]=arg2
within the script, access this array using the $
$
0
=command
$1=arg1
${10}=arg10
note the special format for numbers >10Slide33
Reading user input
read
: reads screen input into a specified variable name
#!/bin/bash -f
echo "Hello. My name is $HOST. What is yours?"
read
firstname
lastname
read is white space delimited
echo "Nice to meet you $
firstname
$
lastname
.”
$./hello.shHello. My name is sailfish.ceri.memphis.edu. What is yours?Heather DeShon [enter]Nice to meet you Heather DeShon.Slide34
Reading (sucking in) multiple lines
The << syntax comes into use
#!/bin/bash –f
cat << END
I have a thousand thoughts in my head
and one line of text is not enough to get them
all out. Hello world.
END
%./
hello.sh
I have a thousand thoughts in my head
and one line of text is not enough to get them
all out. Hello world.Slide35
Alternate
#!/bin/bash –f
cat << EOF
`cat
mythought.dat
`
EOF
%./
hello.sh
I have a thousand thoughts in my head
and one line of text is not enough to get them
all out. Hello world.
Pretend that the sentence appears in a file called
mythought.datSlide36
This is a very powerful way to process data.
my_processing_program
<< END
`
my_convert_program
input file1`
`cat input file2`
END
If we only needed to process file 1 or file2, we could have used a pipe
my_convert_program
input file1 |
my_processing_program
cat input file2 |
my_processing_program
But there is no way
(we have seen so far)
to pipe both outputs into the program (the pipe is serial, not parallel).Slide37
further examples: using it in conjunction with the gmt psmeca command
#!/bin/sh
#missing beginning of script. This command alone will not work
psxy
-R$REGN -$PROJ$SCALE $CONT -W1/$GREEN <<
END
>> $OUTFILE
-69.5 -29.5
-65 -29.5
-65 -33.5
-69.5 -33.5
-69.5 -29.5
`cat
my_map_file.dat
`
ENDSlide38
further examples: running sac from within a script
# Script to pick times in sac file using
taup
# Usage:
picktimes.csh
[directory name]
sacfile
=$1
sac
<< EOF
>&!
sac.log
r
$
sacfile
sss traveltime depth &1,evdp picks 1 phase P S Pn pP Sn sP sS PcP ScS
qs w over
q
EOFSlide39
What does
>&!
mean?
We have already seen the >
(it means redirect output)
and !
(it means clobber any existing files with the same name)
.
There is another standard output stream - introducing
standard-error
. Slide40
$
ls
nonexitantfile
ls
:
nonexitantfile
: No such file or directory
The message above shows up on the screen, but is actually standard-error, not standard-out.
$
ls
nonexitantfile
>
filelist
ls
: nonexitantfile
: No such file or directory$ ls -
l
filelist
-rw-r--r-- 1
smalley
staff 0 Sep 21 16:01
filelist
Can see this by redirecting standard-out into a file. The error message still shows up and the file with the redirected output is empty.
(it has 0 bytes, our standard Unix output, ready for the next command in pipe.)Slide41
>&
is the
csh/tcsh
syntax for redirecting
both
standard-out and standard-error.
(else standard-error it goes to the screen)
Append standard-out and standard-error
>>&
You can’t handle standard-error alone.
(With what we have seen so far, in
csh/tcsh
.)Slide42
In
tcsh
the best you can do is
%( command >
stdout_file
) >&
stderr_file
which runs "command" in a
subshell
.
stdout
is redirected inside the
subshell
to
stdout_file
.
both
stdout
and
stderr
from the
subshell
are redirected to
stderr_file
, but by this point
stdout
has already been redirected to a file, so only
stderr
actually winds up in
stderr_file
. Slide43
Subshells
can be used to group outputs together into a single pipe.
$(command 1; command 2; command 3) | command
when a program starts another program
[more exactly, when a process starts another process]
, the new process runs as a
subprocess
or child process. When a shell starts another shell, the new shell is called a
subshell
.Slide44
The
sh
/bash syntax uses 1 to [optionally] identify standard-out and 2 to identify standard-error.
To redirect standard-error in
sh
/bash use
2>
To redirect standard-error to standard-out
2>&1
To pipe standard-out and standard-error
2>&1|Slide45
Redirect standard-error to file
$
ls
nonexitantfile
>
filelist
2>
errreport
$
cat
errreport
ls
:
nonexitantfile
: No such file or directory
Redirect standard-error and standard-out into a file. Use
subshell
command format, redirect output
subshell
to file.
combofile
has both standard-out and standard-error.
$
(
ls
a.out
nonexistantfile
2>&1)>
combofile
$
more
combofile
nonexistantfile
: No such file or directory
a.Out
Slide46
Special variables
$< : special BSD
unix
csh command
that essentially
acts as
read
except it is not white space
deliminated
set name = “$<“ instead of read
firstname
lastname
$# : the number of arguments passed to the shell
useful when writing
if:then
loops, so we will cover this more next week“$@”: represents all command line arguments at once, maintaining separationsame as “$1” “$2” “$3”“$*” : represents all command line arguments as onesame as “$1 $2 $3 $4”without quotes, $* equals $@Slide47
Special variables
$- : Options given to shell on invocation.
$? : Exit status of previous command.
$$ : Process ID of shell process.
$! : Process ID of last background command.
Use this to save process ID numbers for later use with the wait command.
$IFS : Internal field separator; i.e., the list of characters that act as word separators.
Normally set to space, tab, and newline.Slide48
Special files
/dev/null : the throw away file of the system
useful when writing
if:then
loops, so we will cover this more next week
/dev/
tty
: redirects the script to the terminal
#!/bin/sh -
f
echo "Hello. My name is
hdmacpro
. What is yours?\n"
read name < /dev/
tty
echo "Nice to meet you.\n”
%./hello.shHello. My name is hdmacpro. What is yours?Heather [enter]Nice to meet you.