290 likes | 466 Views
Variables. Variables start with a $ sign when used . The variable gets no $ when declared . Declare a variable with the set command set X = "T" set X = $T set X = 1 set X = 1 + $# Or declare a variable (if it is a number) with the @ command (but you need a space after the “@”)
E N D
Variables Variables start with a $ sign when used. The variable gets no $ when declared. Declare a variable with the set command set X = "T" set X = $T set X = 1 set X = 1 + $# Or declare a variable (if it is a number) with the @ command (but you need a space after the “@”) @ X = $T @ X = 1 @ X = 1 + $# Undeclare a variable with the unset command unset X Only legal if $T is a number! 1
Array Variables • Use ( ) to declare an array • % set var2=(Apple Banana Cherry) • Use [ ] to access an array element • % echo $var2 • Apple Banana Cherry • % echo $var2[2] • Banana • Use - to access ranges • % echo $var2[2-3] • Banana Cherry • % echo $var2[-2] • Apple Banana 2
Array Variables • Use $#X to get the number of elements • % set var2=(Apple Banana Cherry) • % echo $#var2 • 3 • % echo $var2[2-$#var2] • Banana Cherry • Don’t use commas • % set var2=(Apple, Banana, Cherry) • % echo $var2[2] • Banana, • There is a built-in array, argv • There is not much difference between argv[2] and $2, or between $* and argv[*], or between $# and $#argv 3
Positional Parameters $0 : Name of the calling program $1 - $9 : Command-line Arguments The first argument is $1 The second argument is $2, etc. But $10 does not mean 10: % cat testscript echo "The word of the day is $10." % ./testcript at be cat do eat fee go hi it joy kit law The word of the day is at0. (2 digit arguments have to be shifted to use $1- $9)
shift shiftis used in C-shell if you want to access more than 9 parameters. Example: % cat demo_shift #!/bin/tcsh echo $1 $2 $3 shift echo $1 $2 shift echo $1 %. 5
shift shiftis used in C-shell if you want to access more than 9 parameters. Example: % cat demo_shift #!/bin/tcsh echo $1 $2 $3 shift echo $1 $2 shift echo $1 % ./demo_shift 1 2 3 1 2 3 2 3 3 % 6
The $< Special Parameter C shell is a programming language. So we should have a way to read keyboard input (just like other programming languages can). set X = $< or set X = "$<" $< is stdin But if you used “<” file redirection when running the script, then stdin can be a file. What about special symbols? set X = $<:q or set X = "$<" 7
foreach The foreach loop: foreach var ( arrayVariable OR wordlist ) command(s) end
foreach The foreach loop: #!/bin/tcsh foreach person (Bob Susan Joe) echo Hello $person end Output: Hello Bob Hello Susan Hello Joe
foreach • If you want to run a command once for each of a set of filenames, you can use a foreach loop foreach fn (file1 file2 file3 file4) cat $fn | wc end foreach fn (a*b) cat $fn | fgrep Hello | wc -l end set Z = ( A B C ) foreach fn ( $Z ) cat $fn | cut -c1 end
if Two forms: if ( <expression> ) <simple statement> And: if ( <expression> ) then <statements> else if ( <another-expression> ) then <statements> else <statements> endif Some of these spaces are necessary. csh is intensely picky about missing spaces. When in doubt: ADD SPACES! When you get an error message, try fixing it by: ADDING SPACES! 12
Conditional Expressions ! negate != not equal == equal >, <, <=, >= comparators, they work as you would expect =~ If the right hand side matches a pattern, (i.e., similar to filename matching, with asterisks and question marks.) !~ If the right hand side doesn't match a pattern, the condition is true.
Conditional File Tests Before moving on, there is a confusing hazard in C-shell conditional statements… Using the if command, filenames can be tested for the following: if ( -d filename ) # true if filename is a directory if ( -e filename ) # true if filename exists if ( -f filename ) # true if filename is a text file if ( -o filename ) # true if you own filename if ( -r filename ) # true if filename is readable if ( -w filename ) # true if filename is writable if ( -x filename ) # true if filename is executable if ( -z filename ) # true if filename is empty
Conditional Expressionsa tricky expression to test • Suppose you want to write a script that accepts a "-r" option, as an input argument. Well then, the following line will not work: if ( $argv[1] == -r ) echo "The -r flag was given." • If the first argument is "-r" then this is evaluated as: if ( -r =~ -r ) echo "The -r flag was given." • The C shell thinks you meant to use a file operator, and so it tests the file named "=~" to see if it is readable. Then it sees the next operator, which is again a "-r," but in this case there is no filename afterwards. This generates a syntax error. The solution is to place a dummy character before both strings: if ( X$argv[1] =~ X-r ) echo found it
Conditional Expressionsa tricky expression to test • Suppose you want to write a script that accepts a "-r" option, as an input argument. Well then, the following line will not work: if ($argv[1]==-r) echo "The -r flag was given." • If the first argument is "-r" then this is evaluated as: if ( -r == -r ) echo "The -r flag was given." • The C shell thinks you meant to use a file operator, and so it tests the file named "=~" to see if it is readable. Then it sees the next operator, which is again a "-r," but in this case there is no filename afterwards. This generates a syntax error. The solution is to place a dummy character before both strings: if ( X$argv[1] =~ X-r ) echo found it
Conditional Expressionsa tricky expression to test • Suppose you want to write a script that accepts a "-r" option, as an input argument. Well then, the following line will not work: if ($argv[1]==-r) echo "The -r flag was given." • If the first argument is "-r" then this is evaluated as: if ( -r == -r ) echo "The -r flag was given." • The C shell thinks you meant to use a file operator, and so it tests the file named "=~" to see if it is readable. Then it sees the next operator, which is again a "-r," but in this case there is no filename afterwards. This generates a syntax error. The solution is to place a dummy character before both strings: if ( X$argv[1] =~ X-r ) echo found it
Conditional Expressionsa tricky expression to test • Suppose you want to write a script that accepts a "-r" option, as an input argument. Well then, the following line will not work: if ($argv[1]==-r) echo "The -r flag was given." • If the first argument is "-r" then this is evaluated as: if ( -r== -r ) echo "The -r flag was given." • The C shell thinks you meant to use afile operator, and so it tests the file named "==" to see if it is readable. Then it sees the next operator, which is again a "-r," but in this case there is no filename afterwards. This generates a syntax error. The solution is to place a dummy character before both strings: if ( X$argv[1] =~ X-r ) echo found it Needless to say, your directory probably does not contain any file with such a weird name as ==. But, technically speaking, it is legal in UNIX to name a file with such a name.
Conditional Expressionsa tricky expression to test • Suppose you want to write a script that accepts a "-r" option, as an input argument. Well then, the following line will not work: if ($argv[1]==-r) echo "The -r flag was given." • If the first argument is "-r" then this is evaluated as: if ( -r==-r ) echo "The -r flag was given." • The C shell thinks you meant to use afile operator, and so it tests the file named "==" to see if it is readable. Then it sees the next operator, which is again a "-r," but in this case there is no filename afterwards.This generates a syntax error. The solution is to place a dummy character before both strings: if ( X$argv[1] =~ X-r ) echo found it
Conditional Expressionsa tricky expression to test • Suppose you want to write a script that accepts a "-r" option, as an input argument. Well then, the following line will not work: if ($argv[1]==-r) echo "The -r flag was given." • If the first argument is "-r" then this is evaluated as: if ( -r==-r ) echo "The -r flag was given." • The C shell thinks you meant to use afile operator, and so it tests the file named "=~" to see if it is readable. Then it sees the next operator, which is again a "-r," but in this case there is no filename afterwards. This generates a syntax error. The solution is to place a “dummy” character before both strings: if ( X$argv[1] == X-r ) echo "The -r flag was given." This time, if the first argument is “-r”, then the command evaluates as: if ( X-r == X-r ) echo "The -r flag was given" Consequently, the command now works, because, indeed, the X-r string does equal itself.
Conditional Expressionsa tricky expression to test • Suppose you want to write a script that recognizes whether the second command-line parameter begins with "-e”. It then prints that argument, but only if it begins with “-e”. • ./prog 1 2 3 4 • ./prog 1 –e 2 3 -e • ./prog 1 –exyz -exyz
Del Script #!/bin/csh foreach name ($argv) if ( -f $name ) then echo -n "delete the file '${name}' (y/n/q)?" else echo -n "delete the entire directory '${name}' (y/n/q)? " endif set ans = $< switch ($ans) case n: continue case q: exit case y: rm -r $name continue endsw end
Del Script #!/bin/csh foreach name ($argv) # $argv shell variable for an argument of a command if ( -f $name ) then echo -n "delete the file '${name}' (y/n/q)?" else echo -n "delete the entire directory '${name}' (y/n/q)? " endif set ans = $< switch ($ans) case n: continue case q: exit case y: rm -r $name continue endsw end
Del Script #!/bin/csh foreach name ($argv) if ( -f $name ) then #tests to see if the file whose name is in $name is an ordinary file, as opposed to a directory file. echo -n "delete the file '${name}' (y/n/q)?" else echo -n "delete the entire directory '${name}' (y/n/q)? " endif set ans = $< switch ($ans) case n: continue case q: exit case y: rm -r $name continue endsw end
Del Script #!/bin/csh foreach name ($argv) if ( -f $name ) then echo -n "delete the file '${name}' (y/n/q)?” #The echo -n prevents a skip to a new line;the -n option of echo tells the shell not to print the newline # character, so that our answer (“y”, “n”, or “q”), will be on the same line. else echo -n "delete the entire directory '${name}' (y/n/q)? " endif set ans = $< switch ($ans) case n: continue case q: exit case y: rm -r $name continue endsw end
Del Script #!/bin/csh foreach name ($argv) if ( -f $name ) then echo -n "delete the file '${name}' (y/n/q)?” else echo -n "delete the entire directory '${name}' (y/n/q)? " endif set ans = $< #the symbol $<means the input from the keyboard switch ($ans) case n: continue case q: exit case y: rm -r $name continue endsw end
Del Script #!/bin/csh foreach name ($argv) if ( -f $name ) then echo -n "delete the file '${name}' (y/n/q)?" else echo -n "delete the entire directory '${name}' (y/n/q)?" endif set ans = $< switch ($ans) #Control flow is switched to where the first match occurs case n: continue #go to the top of the enclosing loop case q: exit case y: rm -r $name continue endsw end
Del Script #!/bin/csh foreach name ($argv) if ( -f $name ) then echo -n "delete the file '${name}' (y/n/q)?" else echo -n "delete the entire directory '${name}' (y/n/q)?" endif set ans = $< switch ($ans) case n: continue case q: exit case y: rm -r $name #Actually removes the directory (because of -r) continue endsw end