Lecture 4: Writing shell scripts



Similar documents
CS Unix Tools & Scripting Lecture 9 Shell Scripting

Unix Scripts and Job Scheduling

Shell Scripts (1) For example: #!/bin/sh If they do not, the user's current shell will be used. Any Unix command can go in a shell script

BASH Scripting. A bash script may consist of nothing but a series of command lines, e.g. The following helloworld.sh script simply does an echo.

A Crash Course on UNIX

Unix Shell Scripts. Contents. 1 Introduction. Norman Matloff. July 30, Introduction 1. 2 Invoking Shell Scripts 2

Bash shell programming Part II Control statements

Basic C Shell. helpdesk@stat.rice.edu. 11th August 2003

Systems Programming & Scripting

Answers to Even-numbered Exercises

Introduction to Shell Scripting

Hands-On UNIX Exercise:

grep, awk and sed three VERY useful command-line utilities Matt Probert, Uni of York grep = global regular expression print

Unix the Bare Minimum

Lecture 22 The Shell and Shell Scripting

HP-UX Essentials and Shell Programming Course Summary

AN INTRODUCTION TO UNIX

Outline. Unix shells Bourne-again Shell (bash) Interacting with bash Basic scripting References

Introduction to Shell Programming

Command Line - Part 1

Thirty Useful Unix Commands

Lab 1: Introduction to C, ASCII ART and the Linux Command Line Environment

SFTP SHELL SCRIPT USER GUIDE

CS10110 Introduction to personal computer equipment

UNIX, Shell Scripting and Perl Introduction

Running your first Linux Program

Using SVN to Manage Source RTL

Unix Sampler. PEOPLE whoami id who

Computational Mathematics with Python

Linux command line. An introduction to the Linux command line for genomics. Susan Fairley

We will learn the Python programming language. Why? Because it is easy to learn and many people write programs in Python so we can share.

MATLAB Functions. function [Out_1,Out_2,,Out_N] = function_name(in_1,in_2,,in_m)

Outline. Conditional Statements. Logical Data in C. Logical Expressions. Relational Examples. Relational Operators

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C

Computational Mathematics with Python

Computational Mathematics with Python

Member Functions of the istream Class

Learn Perl by Example - Perl Handbook for Beginners - Basics of Perl Scripting Language

PHP Debugging. Draft: March 19, Christopher Vickery

Extreme computing lab exercises Session one

Project 2: Bejeweled

A UNIX/Linux in a nutshell

Linux Shell Script To Monitor Ftp Server Connection

Lecture 2 Mathcad Basics

Beginners Shell Scripting for Batch Jobs

Advanced Bash Scripting. Joshua Malone

Setting up PostgreSQL

Forms, CGI Objectives. HTML forms. Form example. Form example...

VHDL Test Bench Tutorial

New Lab Intro to KDE Terminal Konsole

CS 103 Lab Linux and Virtual Machines

Arduino Lesson 5. The Serial Monitor

32-Bit Workload Automation 5 for Windows on 64-Bit Windows Systems

ESCI 386 IDL Programming for Advanced Earth Science Applications Lesson 6 Program Control

ChE-1800 H-2: Flowchart Diagrams (last updated January 13, 2013)

Visual Basic Programming. An Introduction

An Introduction to the Linux Command Shell For Beginners

Hadoop Hands-On Exercises

CLC Server Command Line Tools USER MANUAL

VIP Quick Reference Card

A Brief Introduction to the Use of Shell Variables

No Frills Command Line Magento

The Linux Operating System and Linux-Related Issues

LECTURE-7. Introduction to DOS. Introduction to UNIX/LINUX OS. Introduction to Windows. Topics:

CSC 120: Computer Science for the Sciences (R section)

Basics of STATA. 1 Data les. 2 Loading data into STATA

Lecture 2 Notes: Flow of Control

CS 2112 Lab: Version Control

Preparing your data for analysis using SAS. Landon Sego 24 April 2003 Department of Statistics UW-Madison

Extreme computing lab exercises Session one

Creating a Simple Macro

CSIL MiniCourses. Introduction To Unix (I) John Lekberg Sean Hogan Cannon Matthews Graham Smith. Updated on:

Example of a Java program

A Simple Shopping Cart using CGI

Command Line Crash Course For Unix

UNIX / Linux commands Basic level. Magali COTTEVIEILLE - September 2009

COMP 110 Prasun Dewan 1

Simple File Input & Output

Introduction to Python

VISUAL GUIDE to. RX Scripting. for Roulette Xtreme - System Designer 2.0

MATLAB Programming. Problem 1: Sequential

L01 Introduction to the Unix OS

Introduction to Python

List of FTP commands for the Microsoft command-line FTP client

Version control tracks multiple versions. Configuration Management. Version Control. V Software Engineering Lecture 12, Spring 2008

Windows PowerShell Essentials

Exercise 4 Learning Python language fundamentals

Unix Shell Scripting Tutorial Ashley J.S Mills

Linux System Administration on Red Hat

Introduction to the UNIX Operating System and Open Windows Desktop Environment

SSH with private/public key authentication

AUTOMATED BACKUPS. There are few things more satisfying than a good backup

PuTTY/Cygwin Tutorial. By Ben Meister Written for CS 23, Winter 2007

1 Basic commands. 2 Terminology. CS61B, Fall 2009 Simple UNIX Commands P. N. Hilfinger

Cisco Networking Academy Program Curriculum Scope & Sequence. Fundamentals of UNIX version 2.0 (July, 2002)

Introduction to Python

Transcription:

Handout 5 06/03/03 1 Your rst shell script Lecture 4: Writing shell scripts Shell scripts are nothing other than les that contain shell commands that are run when you type the le at the command line. That is, the commands that make up a shell script are identical to those you might type at the command prompt, except that they are conveniently stored in a le so that you can execute them over and over again without having to type the commands every time. In order to start editing a shell script, you need to open up a le for editing. You can do so with the emacs editor. Let s say we want to write a very simple shell script called simple.sh that prints the following message to the screen: This shell script was written by me. To do so, open up the emacs edtior with $ emacs -nw simple.sh The emacs editor will appear, and you should enter the following text My rst shell script echo This shell script was written by me. Now, save your le with C-x C-s, and suspend emacs with C-z. You now have a shell script called simple.sh in your current directory. The are comments, and anything after a is ignored by the shell. There are two ways you can execute this script. The rst is by sourcing the script, which just means you want to run the script as if you are typing the commands within it in your current shell. To do so, you just type $../simple.sh This shell script was written by me. All this did was send the lines in your le except for those that started with the to the current shell, which executed the echo command and printed the result to the screen. So running the script is identical to typing the following at the command prompt $ $ My rst shell script $ $ echo This shell script was written by me. This shell script was written by me.

Handout 5 06/03/03 2 From this you can see that typing at the prompt and hitting the return key does nothing. The other way you can execute your script is to make it executable and use it as a command. To make this script executable, use the chmod command $ chmod u+x simple.sh Once the le is executable by the user, you can execute it by typing it at the command line with $./simple.sh This shell script was written by me. Note that this will only work if the permissions on the le are executable by the user. We have to type./simple.sh because the local directory. is not in our search path. This method of running your shell script is identical to typing $ bash./simple.sh This shell script was written by me. which tells the shell to run the program bash and have it read the contents of the le simple.sh. The program bash is the program that is reading the commands as you type them in right now. Sometimes your shell script might be run by someone who prefers to use a different shell, like tcsh. If they tried to run your script at the command line, it might fail because some of the syntax is different between the two languages. When using a different shell, if the user species the correct shell at the command line with $ bash./simple.sh then it doesn t matter which shell is running the command prompt. However, a better way to do it is to specify which shell to run within your script. The way to do this is to include the line!/bin/bash at the beginning of your script, so that now your script looks like!/bin/bash My rst shell script echo This shell script was written by me. Now when you type./simple.sh at the command line, the results will look the same, but the rst line guarantees that a bash shell will open up and interpret the script, even if the calling shell is not bash. The rst line of this script is an exception to the comment rule. If this line were placed at any other line in your script, it would be viewed as a comment.

Handout 5 06/03/03 3 Running your scripts with command line arguments Now let s say we want to add a bit more functionality to our script. Let s say we would like to run our command but have it print out the name we supply to it. For example, let s say we wanted the command to work as follows $./simple.sh Oliver This shell script was written by Oliver. To have the script read the command line arguments, you would use $1 to refer to the rst argument provided at the command line, so that your script now looks like!/bin/bash My rst shell script echo This shell script was written by $1. Now your script will print out This shell script was written by Oliver. when it is called with./simple.sh Oliver. You can add several arguments and treat them all accordingly. For example, if your script looked like this!/bin/bash My rst shell script echo This shell script was written by $1. echo I have written $2 scripts so far. and you ran it with two arguments, you would get $./simple.sh Oliver 2 This shell script was written by Oliver. I have written 2 scripts so far. If you ran this script with no arguments, you would get $./simple.sh This shell script was written by. I have written scripts so far. In the next section, we will deal with learning how to use if statements to check whether or not there are enough arguments and whether or not the supplied arguments make sense.

Handout 5 06/03/03 4 If statements Comparing integers In the script as it is so far, we can run it with as many arguments as we want. We already showed that it could be run with no arguments, but if we ran it with 5 arguments it would also work, but the last three would not be used, such as $./simple.sh Oliver 2 COS315 UNIX 5 This shell script was written by Oliver. I have written 2 scripts so far. We can make sure that there are enough arguments supplied to the script by using the if statement. The number of arguments supplied to the script is given by the $ character, which we can use in the script by adding the line!/bin/bash My rst shell script echo This script has been called with $ arguments. echo This shell script was written by $1. echo I have written $2 scripts so far. If we run this script with the ve arguments, we will get $./simple.sh Oliver 2 COS315 UNIX 5 This script has been called with 5 arguments. This shell script was written by Oliver. I have written 2 scripts so far. Clearly we do not want the script to run when more than two arguments have been called. We can check to see if $ is greater than 2 with the if statement, and if it is, then we should exit the script with a statement that tells us the correct way to use it. The if statement that would do this for us is given in the script as!/bin/bash My rst shell script if [ $ -gt 2 ] ; then echo Usage:./simple.sh name times exit 1; echo This script has been called with $ arguments. echo This shell script was written by $1. echo I have written $2 scripts so far.

Handout 5 06/03/03 5 so that when we run the script we will get $./simple.sh Oliver 2 COS315 UNIX 5 Usage:./simple.sh name times Now let s say we want to also check to see that there are at least two arguments to the script. This is done by editing the if statement so that it reads as if [ $ -gt 2 ] ; then echo Usage:./simple.sh name times exit 1; elif [ $ -le 0 ] ; then echo Usage:./simple.sh name times exit 1; so now if we try and use the script with no arguments then we will get $./simple.sh Usage:./simple.sh name times When you are comparing two integers n1 and n2 using if statements, as we are doing, you use the following n1 -eq n2 n1 -ne n2 n1 -lt n2 n1 -gt n2 n1 -le n2 n1 -ge n2 true when n1 is equal to n2 true when n1 is not equal to n2 true when n1 is less than n2 true when n1 is greater than n2 true when n1 is less than or equal to n2 true when n1 is greater than or equal to n2 In the script we used the exit command to break out of the program when an error was encountered. The particular exit code, or number, that you supply with the exit command is completely arbitrary, except it is standard to have a code exit with an exit code of 0 when no errors have been encountered. The point of the exit code is so that you can determine why your script failed by looking at what the exit code was. For example, given the simple script!/bin/bash exit 5; If we call this script error.sh and run it, nothing is printed to the screen. However, we can determine what its exit code was by looking at the $? variable: $./error.sh $ echo $? 5

Handout 5 06/03/03 6 If you look at the $? variable again, it will be 0, since the echo command exited without errors and the? variable shows the exit code from the last command that was run. Exit codes are useful for debugging very complicated scripts which list the error codes in the documentation for the script. You should employ error codes when you write the script for programming assignment 1. Compound if statements Rather than using two if statements to test both conditions on the arguments, we can use compound if statements as in if [ $ -gt 2 ] [ $ -le 0 ] ; then echo Usage:./simple.sh name times which is identical to using two if statements except that it is more compact. Here, the characters imply the or logical operator. The or logical operator can also be used in the form if [ $ -gt 2 -o $ -le 0 ] ; then echo Usage:./simple.sh name times We can also use the and logical operator with is given by either [ $ -gt 2 -a $ -le 0 ] or [ $ -gt 2 ] && [ $ -le 0 ] You should note that both of these statements would never be true since $ could never be greater than 2 and less than or equal to 0 at the same time, but these are used only to illustrate the syntax. Checking existence of les or directories Now let s say we want to use the if statement to test whether or not a directory we supply at the command line exists. This is done using if [ -d $1 ] ; then echo The directory exists! else echo The directory does not exist! If these lines are used in a shell script, which is called test.sh and run, then we get

Handout 5 06/03/03 7 $./test.sh /home/ofringer The directory exists! We can also use this syntax to test the existence of regular les (not block or character les, which are tested with -b and -c) with the -f option instead of -d. If we want do check and see if a given argument is not a le, we use if [! -f $1 ] ; then echo The le does not exist! else echo The le does exist! Comparing strings The if statement can also be used to compare strings. For example, let s say we wanted to check and see if a command line argument matched the string info. This would be done with str= info if [ $1 = $str ] ; then echo The string matches. We can also check to see if it does not match it with!=. In order to check and see if strings are empty, we use the -z option, as in str= info if [ -z $1 ] ; then echo The string is empty! For loops For loops are used to execute commands on each le in a given list. For example, if we wanted our test.sh script to list the jpeg les in the directory provided, say the images directory from /home/cos315/assignments/assignment1/images, our shell script would look something like!/bin/bash for le in $1/*.jpg do echo $le done So that when we run the script we get

Handout 5 06/03/03 8 $./test.sh images images/img_5974.jpg images/img_6005.jpg images/img_6017.jpg images/img_6288.jpg images/img_6345.jpg images/img_6366.jpg images/img_6764.jpg images/img_6830.jpg images/img_7435.jpg images/img_7461.jpg images/img_7658.jpg images/img_7731.jpg Now let s say we wanted to count the number of les in the directory. In order to do so, we need to use the expr command, which evaluates arithmetic expressions. For example, at the command line, if we wanted to add two numbers x and y, we would type $ x=3;y=2;expr $x + $y 5 We can also subtract two numbers with $ x=3;y=2;expr $x - $y 5 The expr command can then be used in the for loop to count the number of les in the directory with!/bin/bash n=0 for le in $1/*.jpg do n= expr $n + 1 done echo There are $n les in the directory $1. so that typing the script at the command line would result in $./test.sh images There are 12 les in the directory images. Of course, we can use other already existing functions to count the number of les in the directory images with $ ls images/*.jpg wc -w 12 Which we can in turn use to test if there are any jpeg les in the directory with

Handout 5 06/03/03 9 numles= ls $1/*.jpg wc -w if [ $numles -eq 0 ] ; then echo There are no jpeg les in the directory $1! So, using the above as a script, if we made an empty directory with mkdir empty, and tried to count the number of jpg les in that directory, we would get $./test.sh empty ls: empty/*.jpg: No such le or directory There are no jpeg les in the directory empty. In order to remove the error with the ls command, we could redirect its standard error into the UNIX trash le /dev/null with numles= ls $1/*.jpg 2> /dev/null wc -w if [ $numles -eq 0 ] ; then echo There are no jpeg les in the directory $1! so that we do not see the error associated with ls when it doesn t nd the specied le. The /dev/null le is a special le that you can use to redirect messages to that you do not want to appear on the screen. We can employ if statements within the for loop if we would like to list out the les in a specied number of groups with a specic number in each group. If the number of groups was the second argument provided at the command line, then the script to do so would be given by!/bin/bash dir=$1 gps=$2 n=1 for le in $dir/*.jpg do echo $le if [ $n -eq $gps ] ; then n=1 echo ; else n= expr $n + 1 done So that calling this script would yield

Handout 5 06/03/03 10 $./test.sh images 4 images/img_5974.jpg images/img_6005.jpg images/img_6017.jpg images/img_6288.jpg images/img_6345.jpg images/img_6366.jpg images/img_6764.jpg images/img_6830.jpg images/img_7435.jpg images/img_7461.jpg images/img_7658.jpg images/img_7731.jpg Which shows that the script prints out the images in the images directory in three groups, each group listing four les.