Up: The Shell

Variables

slide 01 Hello, and welcome to episode number eight of the Software Carpentry lecture on the Unix shell. In this episode, we’ll have a look at shell variables.
slide 02 As you’ve heard several times by now, we’re looking at how to interact with a computer using a command-line shell.
slide 03 The shell is just a program…
slide 04 …and like other programs, it has variables.
slide 05 Those variables control its execution, and by changing their values, you can change how the shell and other programs behave.
slide 06 Let’s start by running the command set and looking at some of the variables in a typical shell session. As you can see, there are quite a few—in fact, four or five times more than what’s shown on this slide.
slide 07 Using set to show things might seem a little strange, even for Unix, but if you don’t give it any arguments, it might as well show you things you could set.
slide 08 Every variable has a name. By convention, variables that are always present are given upper-case names.
slide 09 All shell variables’ values are strings.
slide 10 It’s up to programs to convert these strings to other types when necessary.
slide 11 For example, if a program wanted to find out how many processors the computer had, it would convert the NUMBER_OF_PROCESSORS variable from a string to an integer.
slide 12 Some variables store lists of values. Here, the convention is to use a colon ‘:’ as a separator. If a program wants the individual elements of such a list, it’s the program’s responsibility to split the variable’s string value into pieces.
slide 13 Let’s have a closer look at one of the most important of those list-valued variables, PATH. Its value defines the shell’s search path, i.e., the directories that the shell looks in for runnable programs.
slide 14 If you recall from a couple of episodes ago, if we type a command like ./analyze, with a specific directory in the path, the shell runs the program that path specifies.
slide 15 Similarly, if we type /bin/analyze, the shell runs that specific program: we’ve provided a specific path, so it knows what to do.
slide 16 But what should the shell do if we just type analyze? There are at least two things it could run: how should it choose?
slide 17 Its rule is simple. The shell checks each directory in the PATH variable in turn, looking for a program with the rqeuested name in that directory. As soon as it finds a match, it stops searching and runs the program.
slide 18 To show how this works, here are the components of PATH broken out one per line.
slide 19 On our computer, there are actually three programs called analyze in three different directories.
slide 20 Since the shell searches the directories in order, it finds the one in /bin, not either of the others.
slide 21 Notice that it will never find the program /users/vlad/analyze, since the directory /users/vlad isn’t in our path.
slide 22 Before we explore variables any further, let’s introduce one more command: echo. All it does is print out its argument.
slide 23 This doesn’t sound very exciting, but we can use it to show variables’ values.
slide 24 First, let’s make sure it works. Yup: echo hello transylvania! prints hello transylvania! as promised.
slide 25 Now let’s try to show the value of the variable HOME with echo HOME.
slide 26 Whoops: that just prints “HOME”.
slide 27 Let’s try this instead: echo $HOME.
slide 28 The dollar sign tells the shell to replace the variable’s name with its value.
slide 29 This works just like wildcards: the shell does the expansion before running the program we’ve asked for.
slide 30 Thanks to this expansion, what we actually run is echo /home/vlad, which shows us the variable’s value.
slide 31 Creating a variable is easy: just assign a value to a name using “=”.
slide 32 Changing a value is equally easy: just assign the new value.
slide 33 Here, we set our secret identity to be Dracula, check it, change it to Camilla, and check again.
slide 34 It’s important to note, though, that assignment only changes a variable’s value in the current shell, not in any other shells that are currently running, or in any shells that are started later.
slide 35 Let’s go back and set our secret identity once again.
slide 36 Once it’s set, let’s run a fresh copy of the shell by typing the command bash.
slide 37 We now have two copies of the shell running: the original, shown in green, and its child, shown in orange.
slide 38 If we echo $SECRET_IDENTITY in the child shell, nothing is printed, because the variable doesn’t have a value.
slide 39 If we exit the child shell and return to the original…
slide 40 …we can see that yes, the variable does exist.
slide 41 If we really want the shell to pass a variable to the processes it creates, we must use the export command.
slide 42 Let’s try the secret identity example again. After giving SECRET_IDENTITY a value, we give the shell the command export SECRET_IDENTITY. (Note, by the way, that it’s not export $SECRET_IDENTITY with a dollar sign: if we typed that, the shell would expand SECRET_IDENTITY, and our export command would actually be export Dracula, which would do nothing, because there’s no variable called Dracula.)
slide 43 Now let’s run a new shell…
slide 44 …and type echo $SECRET_IDENTITY. Yup: there’s our variable.
slide 45 And of course, exiting brings us back to our original shell.
slide 46 If we want to set some variables’ values automatically every time we run a shell, we can put the command to do this in a file called .bashrc in our home directory. The ‘.’ character at the front prevents ls from listing this file unless we specifically ask it to using -a—we normally don’t want to worry about it—and the “rc” at the end is an abbreviation for “run control”, which meant something really important decades ago, and is now just a convention everyone follows without understanding why.
slide 47 For example, here are two lines in Vlad’s .bashrc file. These two lines create the variables SECRET_IDENTITY and BACKUP_DIR, give them values, and export them so that any programs the shell runs can see them as well.
slide 48 And while we’re here, it’s also common to use the alias command to create shortcuts for things we frequently type.
slide 49 For example, we can define the alias backup to run /bin/zarble with these arguments. Notice that these arguments include references to some variables, so that if we want to change where we put our backups, we only have to change one variable’s value in one place.
slide 50 As you can see, aliases can save us a lot of typing, and a lot of typing mistakes.
slide 51 In our next episode, we’ll have a look at how to connect to other machines securely.

  1. @IsaacG2
    September 2nd, 2010 at 17:29 | #1

    All cap vars should be reserved for internal variables.
    When making your own lists, bash arrays are “better” than trying to use a list with a delimiter like :
    Variables should be quoted, especially in cased like your alias; what if the backup directory has a space in the name?
    Trivia: try using ‘echo’ to print ‘-n’

  2. Kristine Yu
    January 30th, 2011 at 06:36 | #2

    A note that whitespace is important in shell scripting. A beginning user might type

    SECRET_IDENTITY = DRACULA

    rather than

    SECRET_IDENTITY=DRACULA

    and not know what went wrong.

  1. No trackbacks yet.