Variables

A script can be a braindead list of commands that you've created using something like ls > braindead , then edit this file to do the same thing on all the files, then run it. These are single use scripts that you'll probably never use again but sometimes this kind of scripting is useful. As you gain experience, you'll be able to create these from the command line directly without having to use an intermediate file.

In csh, variables are set using the set command. And to tell the shell that something is a set variable you precede the name with a $:

#!/bin/csh

set myvar = "This is my var"

echo "I just set myvar = $myvar"

Running this script will print this to your screen:

I just set myvar = This is my var

Using the ` (back tick) you can set variables equal to the output of a command:

#!/bin/csh

set myvar = `date`
echo "todays date is $myvar"

which will put the following on your screen:

todays date is Fri Feb 16 10:38:32 CST 2001

And of course you can combine commands, use redirects and pipes and all the other good stuff associated with UNIX. You can also do loops with the foreach command:

#!/bin/csh

set myvar = `/bin/date -u +%c%m%d%H | /bin/awk '{print $5}'`

echo looking for files named $myvar

foreach todayfile (`find . -name $myvar`)
  echo moving $today $todayfile.found
  /bin/mv $todayfile $todayfile.found
end

which will print this to the screen and move the files found (or rename for those of you who are chronically MicroShafted):

looking for files named 2001021616
moving ./tmp/2001021616 ./tmp/2001021616.found

Had there been more than one file in the . directory tree, all of them would have gained the .found extension. First the find command is run and generates a list of all the found files (hopefully you won't get permission denied problems, be lets not get side tracked). Then for each of the files (includes path relative to . but exclude .. thankfully) first we echo to the screen (actually stdout) that we're about to move the first on the list, the we actually move it, then we go round again for the second entry on the list. Only the commands between the foreach and end lines are performed on the list.

But why did I use /bin/mv instead of just mv? I have tons of aliases many of which are just standard shell commands with the switches I like to help avoid typing my favorite switches every time. You can undo the alias by using \mv but it is still better to give the full path. Because if your path includes a directory that contains a mv command that is not standard, using the absolute path guarantees the behavior of mv regardless of what you do to your path or aliases. This also helps in case you've made bad file names or variable names like test (which is a command).

I may wish to keep a record of what I did to the files instead of spewing it to the screen:

#!/bin/csh
 
set myvar = `/bin/date -u +%c%m%d%H | /bin/awk '{print $5}'`
set logfile = mylog

# make sure the log exists else the cat redirect will biff:
touch mylog
 
echo looking for files named $myvar

foreach todayfile (`find . -name $myvar`)
  echo $todayfile.found >> mylog
  /bin/mv $todayfile $todayfile.found
end