Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near...

27
Ryan Hulguin

Transcript of Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near...

Page 1: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Ryan Hulguin

Page 2: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Why Shell Programming is Part of the Seminar Series on High Performance Computing?

• The majority of the Portable Batch System (PBS) submission scripts are written in Bash – This allows you to queue up jobs on clusters/

supercomputers

• Many pre/post processing steps are easier when automated – gathering and analyzing input/output data

Page 3: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Active participation

• It is highly encouraged to try all the examples as we go along

• You may use your own shell from a Linux/Mac terminal

• You may also use the free linux shell provided by http://simpleshell.com

Page 4: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Archive data output example

• Suppose you had a program which generated output for density, velocity and temperature in the files: den.dat, vel.dat, and temp.dat

• This example will copy the files into a folder based on the date, and then archive them

• Before we write the shell script, let’s create these .dat files using IO redirection

Page 5: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Generating .dat files

echo –e “1.0\n2.5\n3.0” > den.dat

echo –e “0.0 3.0\n0.2 2.5\n 0.4 2.0” > vel.dat

echo –e “273.5\n284.2\n286.7” > temp.dat

•  The \n inserts a newline or hard return •  the –e flag is needed to enable the interpretation the

backslash escapes •  the > redirects the output from the terminal to the file

specified •  Verify the contents of the .dat files using cat

cat den.dat cat vel.dat cat temp.dat

Page 6: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The Archive data script # Get today’s date TODAYS_DATE=$(date “+%m_%d_%y) # create directory of today’s date mkdir $TODAYS_DATE # For every .dat file copy it to the new # folder for DATFILE in $(ls *.dat) do

cp –v $DATFILE ./$TODAYS_DATE done cd $TODAYS_DATE # Archive all the .dat files tar –zcvf archived_data.tar.gz *.dat rm *.dat cd ..

Page 7: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The test utility

• test evaluates conditional expressions test expression [ expression ]

• If the expression to be evaluated is true, 0 is returned

• If the expression to be evaluated is false, 1 is returned

• If an error occurs, a number greater than 1 is returned

• The return value can be displayed using $?

Page 8: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Comparing integers with test

• Two integers can be compared using the following comparisons

• [ INTEGER1 –eq INTEGER2 ] [ INTEGER1 –ne INTEGER2 ] [ INTEGER1 –gt INTEGER2 ] [ INTEGER1 –ge INTEGER2 ] [ INTEGER1 –lt INTEGER2 ] [ INTEGER1 –le INTEGER2 ]

• The equivalent symbols can also be used The < and > signs need to be escaped \< and \> Make sure there are spaces around = [ INTEGER1 = INTEGER2 ]

Page 9: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Comparing strings with test • Test if the length of STRING1 is nonzero [ -n STRING1 ]

• Test if the length of STRING1 is zero [ -z STRING1 ]

• Test if STRING1 and STRING2 are identical [ STRING1 = STRING2 ]

• Test if STRING1 and STRING2 are not identical [ STRING1 != STRING2 ]

Page 10: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Common file tests

[ -operator FILENAME ]

operator characteristic -d directory -e or -a exists -f file -h or -L symbolic link -r readable by you -s not empty -w writable by you -N has been modified since last

being read

Page 11: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Comparing pairs of files with test

• Test if FILE1 is newer than FILE2 [ FILE1 –nt FILE2 ]

• Test if FILE1 is older than FILE2 [ FILE1 –ot FILE2 ]

• Test if FILE1 and FILE2 refer to the same thing (either hard or symbolic link)

[ FILE1 –ef FILE2 ]

Page 12: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Integer arithmetic

• Integer arithmetic expressions can be evaluated using $(( EXPRESSION ))

• Example COUNT=1 COUNT=$((2+COUNT)) echo $COUNT

• Note how the shell variable did not a $ in front of it

• Input parameters still need the $

Page 13: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The let statement

• The previous arithmetic expression COUNT=$((2+COUNT)) can also be expressed using the let statement

• let COUNT=COUNT+2 • let COUNT+=2

Page 14: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The compound command

• Integer arithmetic expressions can serve as command by dropping the $

• (( EXPRESSION )) • If the EXPRESSION evaluates to zero, then a

return value of 1 is given • If the EXPRESSION evaluates to a nonzero

number, then a return value of 0 is given • Example: (( 3 + 3 )); echo $? (( 3 – 3 )); echo $?

Page 15: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The if…then control structure

• if test-command then commands

fi

• The test-command is a conditional expression i.e. [ $AGE –gt 18 ]

• For every if there must be a matching fi

Page 16: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The if…then…else control structure

•  if test-command then commands else commands

fi

• Here we can specify what should be done if the test-command evaluates to false

• You may also use a semicolon to make it look cleaner •  if test-command; then

commands else commands

fi

Page 17: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The if…then…elif control structure

• if test-command then commands elif test-command

then commands

fi

• elif is a combination of else and if • Multiple elif blocks can be nested

Page 18: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The while control structure

• while test-command do

commands done

• Example: # Echo the contents of input1.in while read LINE do

echo $LINE done < "input1.in"

Page 19: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The until control structure

• until test-command do

commands done

• This is equivalent to while !test-command • The loop will continue to run until the test-

command evaluates to true

Page 20: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

break and continue

• The for, while, or until control structures can be interrupted using a break or continue statement

• break terminates the execution of the loop and then begins executing statements immediately following the done statement

• continue jumps immediately to the done statement and skips all the statements in between

Page 21: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The case structure

• case test-string in pattern-1) commands-1 ;; pattern-2) commands-2 ;; pattern-3) commands-3 ;;

… esac

Page 22: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

case structure example

read –p “Choose either A, B, or C: ” letter case “$letter” in

A) echo “You chose A” ;; B) echo “You chose B” ;; C) echo “You chose C” ;; *) echo “You did not choose properly” ;;

esac

Page 23: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The select control structure

• select varname [ in arg … ] do

commands done

• A menu will be formatted with numbers before each item

• When a user selects a number, varname will be set to the appropriate arg

Page 24: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

The select example

# Create menu from input files using select

# This particular example only accepts input1.in

select OPTION in $(ls *.in)

do

if [ $OPTION = "input1.in" ]

then

echo "Using $OPTION"

break

else

echo "$OPTION is not a valid choice at this time"

fi

done

Page 25: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Debugging shell scripts

• There may be times where a shell script does something unexpected (due to user error of course)

• It may be helpful to see exactly what commands the shell is currently executing

• This can be done in several ways 1.  Call your script with /bin/bash –x myscript.sh 2.  Insert the line set –x near the top of the script 3.  Modify the SHEBANG to be #!/bin/bash –x

• If you want to monitor the input as well, use -xv instead of -x

Page 26: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

References

• A Practical Guide to Linux® Commands, Editors, and Shell Programming by Mark G. Sobell

• Bash Cookbook: Solutions and Examples for Bash Users by Carl Albing, JP Vossen, and Cameron Newham

• http://en.wikibooks.org/wiki/Bash_Shell_Scripting

• These slides will be posted on http://www.nics.tennessee.edu/hpc-seminar-series

Page 27: Ryan Hulguin...1. Call your script with /bin/bash –x myscript.sh 2. Insert the line set –x near the top of the script 3. Modify the SHEBANG to be #!/bin/bash –x • If you want

Questions? / Contact

• Ryan Hulguin

[email protected]