1 00:00:00,000 --> 00:00:02,320 [Seminar - Unix Shells, Environments] 2 00:00:02,320 --> 00:00:04,180 [Douglas Kline - Harvard University] 3 00:00:04,180 --> 00:00:07,160 [This is CS50. - CS50.TV] 4 00:00:07,160 --> 00:00:12,770 >> Today's topic is the Unix shell. 5 00:00:12,770 --> 00:00:20,600 I'm Douglas Kline, expert, or at least reasonably competent user, of the shell. 6 00:00:20,600 --> 00:00:25,280 A shell is the interface for the user to the computer's operating system. 7 00:00:25,280 --> 00:00:29,580 The name is misleading as, unlike an animal's shell, 8 00:00:29,580 --> 00:00:34,890 which is hard and protective, the computer shell allows for communication. 9 00:00:34,890 --> 00:00:39,120 So porous membrane would probably be a better metaphor. 10 00:00:39,120 --> 00:00:44,500 >> The original shell for Unix is the Bourne shell. 11 00:00:44,500 --> 00:00:46,450 Bourne is spelled B-O-U-R-N-E. 12 00:00:46,450 --> 00:00:49,770 Bourne was one of the original authors of Unix, 13 00:00:49,770 --> 00:00:51,700 and so the shell is named after him. 14 00:00:51,700 --> 00:00:54,850 The name of that shell as a command is just simply sh. 15 00:00:54,850 --> 00:00:57,400 That's the command you can execute. 16 00:00:57,400 --> 00:01:00,810 The shell starts at login. 17 00:01:00,810 --> 00:01:04,459 When you log in to the computer, the shell just starts running for you, 18 00:01:04,459 --> 00:01:06,820 and that's what takes your commands. 19 00:01:06,820 --> 00:01:09,790 It can start at other times also. 20 00:01:09,790 --> 00:01:16,780 If you bring up a window with no other indication, it will start a shell for you. 21 00:01:16,780 --> 00:01:20,450 That's how it is that you can go to a window and start typing commands 22 00:01:20,450 --> 00:01:23,960 and so forth there even though you didn't log in to that window. 23 00:01:23,960 --> 00:01:26,670 In addition, if you do a remote login, 24 00:01:26,670 --> 00:01:30,250 then it will start a shell on the remote computer. 25 00:01:30,250 --> 00:01:44,310 And it's possible to run commands without an interactive shell. 26 00:01:44,310 --> 00:01:48,990 That can mean within your current operation, 27 00:01:48,990 --> 00:01:50,700 and it can also mean a remote operation. 28 00:01:50,700 --> 00:01:52,900 You could send a command to another computer, 29 00:01:52,900 --> 00:01:55,460 which includes starting up a shell there. 30 00:01:55,460 --> 00:01:57,760 In fact, it has to include starting up a shell there 31 00:01:57,760 --> 00:02:01,740 even if that isn't your final purpose. 32 00:02:05,310 --> 00:02:12,350 When something starts up like this, it doesn't necessarily start a new shell. 33 00:02:12,350 --> 00:02:17,430 If you bring up a new window, it's possible to tell it to bring up an editor 34 00:02:17,430 --> 00:02:18,940 or some other command. 35 00:02:18,940 --> 00:02:20,560 In that case, the editor will start from scratch. 36 00:02:20,560 --> 00:02:22,930 When the editor ends, the window ends. 37 00:02:22,930 --> 00:02:24,620 This is a little unusual but it can be done. 38 00:02:24,620 --> 00:02:27,140 In those cases, it won't be a shell. 39 00:02:27,140 --> 00:02:31,890 So it's not necessarily the case that a window or some such application will bring up a shell. 40 00:02:31,890 --> 00:02:34,030 >> Shell parses commands. 41 00:02:34,030 --> 00:02:40,900 Parsing means identifying the various elements and classifying them. 42 00:02:40,900 --> 00:02:43,470 Within a command, the complete string that you type, 43 00:02:43,470 --> 00:02:47,310 there will be 1 or more single commands to be executed. 44 00:02:47,310 --> 00:02:50,050 Other elements can be arguments. 45 00:02:50,050 --> 00:02:55,020 There can also be special characters which affect the execution of a command. 46 00:02:55,020 --> 00:02:59,710 They can send the output somewhere other than the screen 47 00:02:59,710 --> 00:03:01,750 if the command would ordinarily send it to the screen. 48 00:03:01,750 --> 00:03:04,390 It can redirect input; it can do other things also. 49 00:03:04,390 --> 00:03:08,120 There are various other symbols, characters, and so forth. 50 00:03:08,120 --> 00:03:13,600 Parsing involves detecting and interpreting those things. 51 00:03:13,600 --> 00:03:19,560 >> Now if there are no more questions, which is rather likely since there are no more people, 52 00:03:19,560 --> 00:03:24,620 we will go on to my next page here. 53 00:03:24,620 --> 00:03:29,170 >> I said earlier that the Bourne shell is the initial shell. 54 00:03:29,170 --> 00:03:31,550 There are others. 55 00:03:31,550 --> 00:03:34,520 One is the C-shell. The command is csh. 56 00:03:34,520 --> 00:03:36,830 The name C-shell is just a play on words. 57 00:03:36,830 --> 00:03:41,260 This shell was introduced with Berkeley Unix in the mid-1970s. 58 00:03:41,260 --> 00:03:44,830 Berkeley Unix was a seminal event in the development of Unix. 59 00:03:44,830 --> 00:03:48,770 It was a huge revolution and included the introduction of this shell. 60 00:03:48,770 --> 00:03:50,790 The reason for that play on words, C-shell, 61 00:03:50,790 --> 00:03:56,490 is that the C-shell has some characteristics in it which resemble the C language, 62 00:03:56,490 --> 00:03:59,740 which the Bourne shell does not have-- 63 00:03:59,740 --> 00:04:02,140 or it did not have at that time. 64 00:04:02,140 --> 00:04:05,190 There's also the TC-shell. 65 00:04:05,190 --> 00:04:07,360 This is a superset of the C-shell. 66 00:04:07,360 --> 00:04:11,470 It has additional features, many of which are useful for interactive use, 67 00:04:11,470 --> 00:04:16,050 such as recalling commands in the history mechanism, 68 00:04:16,050 --> 00:04:18,459 which I'll describe somewhat later-- 69 00:04:18,459 --> 00:04:23,120 in a simple manner, modeled after an editor. 70 00:04:23,120 --> 00:04:29,170 It also has bindings which allow you to bind a short key string to a longer command. 71 00:04:29,170 --> 00:04:31,440 We're not going to be getting into that today. 72 00:04:31,440 --> 00:04:33,650 It has some features that are useful for programming. 73 00:04:33,650 --> 00:04:37,020 However, the C-shell is not often used for shell programming. 74 00:04:37,020 --> 00:04:39,080 Shell programs, if you didn't already know, 75 00:04:39,080 --> 00:04:41,690 are programs that consist of shell characteristics. 76 00:04:41,690 --> 00:04:43,220 You could run these as programs. 77 00:04:43,220 --> 00:04:46,760 You write a bunch of shell commands into a file and execute the file. 78 00:04:46,760 --> 00:04:49,760 You don't need to compile it. This is an interpretive language. 79 00:04:49,760 --> 00:04:57,320 The phrase C-shell is now ambiguous since it might refer only to the original C-shell, csh, 80 00:04:57,320 --> 00:05:01,200 or to all C-shells, including tcsh. It's a little ambiguous. 81 00:05:01,200 --> 00:05:08,250 >> A later shell is the Korn shell, ksh, named after the programmer, Korn. 82 00:05:08,250 --> 00:05:14,160 This shell attempted to incorporate into 1 shell 83 00:05:14,160 --> 00:05:16,960 the advantages of the C-shell for interactive use 84 00:05:16,960 --> 00:05:19,230 and the Bourne shell for programming. 85 00:05:19,230 --> 00:05:25,440 It has been used as an interactive shell by some people--a minority. 86 00:05:25,440 --> 00:05:32,050 Later though, there was another introduction, the Bash shell, B-A-S-H, 87 00:05:32,050 --> 00:05:35,290 again a play on words, Bourne-again shell. 88 00:05:35,290 --> 00:05:43,830 It's an extension of the Bourne shell. Korn shell is also. Both of them are. 89 00:05:43,830 --> 00:05:48,100 It has the same objectives of the Korn shell of amalgamating the C-shell's 90 00:05:48,100 --> 00:05:50,980 and Bourne shell's advantages in 1 shell. 91 00:05:50,980 --> 00:05:56,810 Many of the enhancements of the Korn shell are also included in Bash. 92 00:05:56,810 --> 00:06:00,710 Bash, however, has more and is therefore preferable. 93 00:06:00,710 --> 00:06:05,180 The Bourne-again shell and the Korn shell are called Bourne-type shells 94 00:06:05,180 --> 00:06:07,730 because they include the Bourne shell's characteristics, 95 00:06:07,730 --> 00:06:11,180 which are incompatible in some respects with C-shells. 96 00:06:11,180 --> 00:06:15,520 There are other shells besides those, some intended for restricted use, 97 00:06:15,520 --> 00:06:20,670 maybe limited to some commands, maybe specialized purposes, not often used. 98 00:06:20,670 --> 00:06:24,240 >> Okay. Next item here. 99 00:06:31,300 --> 00:06:38,970 The Bash shell has become associated with various forms of Linux. 100 00:06:38,970 --> 00:06:41,550 I'm not sure if that's true of every form. 101 00:06:41,550 --> 00:06:43,280 There are many forms out there and I haven't used them all, 102 00:06:43,280 --> 00:06:46,870 but in those that I have used it has become associated with it. 103 00:06:46,870 --> 00:06:49,670 So far as I know, there is nothing about Bash 104 00:06:49,670 --> 00:06:52,210 which makes it any more compatible with Linux 105 00:06:52,210 --> 00:06:55,020 than any other combination of shell and operating system. 106 00:06:55,020 --> 00:06:59,690 I think this probably just reflects the inclinations of the programmers. 107 00:06:59,690 --> 00:07:07,500 That it has become associated with Linux is another reason to prefer Bash to ksh 108 00:07:07,500 --> 00:07:11,820 since things are likely to be written in it and it's likely to spread. 109 00:07:11,820 --> 00:07:15,410 I'll give you other reasons for that later on. 110 00:07:15,410 --> 00:07:21,330 Bourne shell scripts should run under the Korn shell or Bash. 111 00:07:21,330 --> 00:07:22,650 If you write something for the Bourne shell, 112 00:07:22,650 --> 00:07:26,180 you can probably execute it under ksh or bash. 113 00:07:26,180 --> 00:07:30,610 Korn shell scripts will probably run under Bash, but I can't guarantee that. 114 00:07:30,610 --> 00:07:36,040 Later on here, C-shell scripts should run under the TC-shell. 115 00:07:38,850 --> 00:07:41,690 The C-shell was actually never extensively used for scripting 116 00:07:41,690 --> 00:07:48,110 since the Bourne shell and later the Bourne-type shells were preferable for that purpose. 117 00:07:48,110 --> 00:07:50,620 So that really isn't all that important. 118 00:07:50,620 --> 00:07:53,480 There are quite a lot of Bourne shell scripts which were written long ago, 119 00:07:53,480 --> 00:07:56,860 before the Korn shell or the Bourne-again shell were introduced. 120 00:07:56,860 --> 00:07:59,300 Those are still in use, part of the operating systems, 121 00:07:59,300 --> 00:08:01,590 and so you will find them if you look into the operating system 122 00:08:01,590 --> 00:08:03,760 or some old programming packages. 123 00:08:03,760 --> 00:08:12,840 >> Bash is to some extent becoming a kind of lingua franca for operating systems. 124 00:08:12,840 --> 00:08:17,580 It's already been extended to Windows and to VMS. 125 00:08:17,580 --> 00:08:20,440 VMS, in case you don't know, is a proprietary operating system 126 00:08:20,440 --> 00:08:25,480 of Digital Equipment Corporation which is still in use, largely behind the scenes. 127 00:08:25,480 --> 00:08:29,250 And if it's going to be running on several different operating systems, 128 00:08:29,250 --> 00:08:31,110 likely the people tend to shift for it. 129 00:08:31,110 --> 00:08:33,840 But this development is relatively recent. 130 00:08:33,840 --> 00:08:39,490 It's just beginning, so I can't predict if this will turn out to really be that kind of lingua franca. 131 00:08:39,490 --> 00:08:43,539 Also, because file pathnames and libraries differ 132 00:08:43,539 --> 00:08:46,210 between these different operating systems, 133 00:08:46,210 --> 00:08:50,250 you might not be able to write a Bash script on one operating system 134 00:08:50,250 --> 00:08:51,840 and then run it on another one. 135 00:08:51,840 --> 00:08:54,440 You should be able to move it between different Unix, Linux 136 00:08:54,440 --> 00:08:59,020 Mac OS operating systems but not necessarily to Windows or VMS. 137 00:08:59,020 --> 00:09:01,390 You might have to change file pathname descriptions, 138 00:09:01,390 --> 00:09:03,180 and some libraries might be different, 139 00:09:03,180 --> 00:09:05,230 which may affect the way that some commands work 140 00:09:05,230 --> 00:09:09,730 or how they process arguments and the like. 141 00:09:09,730 --> 00:09:19,230 In addition to that, another caution here is that there is no guarantee 142 00:09:19,230 --> 00:09:23,570 that all the different shells I've mentioned--Bourne shell, C-shell, 143 00:09:23,570 --> 00:09:29,880 TC-shell, Korn shell, Bourne-again shell--will be available under any Unix 144 00:09:29,880 --> 00:09:33,750 or Linux or Mac OS computer. 145 00:09:33,750 --> 00:09:35,620 They simply might not be there. 146 00:09:35,620 --> 00:09:38,300 That's one of the cautions here. 147 00:09:38,300 --> 00:09:41,490 It's an unfortunate limitation here since you'd like things to work everywhere, 148 00:09:41,490 --> 00:09:44,380 but unfortunately, you can't rely on that. 149 00:09:44,380 --> 00:09:47,230 >> Okay. Next one here. 150 00:09:50,280 --> 00:09:54,370 Let's say that you want to write a shell script, 151 00:09:54,370 --> 00:09:57,170 a program consisting of shell commands. 152 00:09:57,170 --> 00:10:01,200 You write your commands, put them in a file, and execute the file. 153 00:10:01,200 --> 00:10:04,230 What if you want to include arguments? 154 00:10:04,230 --> 00:10:09,650 In the case of shell operations, arguments are called parameters or positional parameters 155 00:10:09,650 --> 00:10:15,940 and they'll be called by a dollar sign and numeral, $1, $2. 156 00:10:15,940 --> 00:10:27,000 So if the script has this name, my first argument might be argument 1 157 00:10:27,000 --> 00:10:30,540 and my second might be argument 2, 158 00:10:30,540 --> 00:10:34,110 and inside my script if I want to refer to these things-- 159 00:10:34,110 --> 00:10:36,810 let's erase this since I'm not really going to run it-- 160 00:10:36,810 --> 00:10:42,160 inside my script I might have $1 to refer to arg1, 161 00:10:42,160 --> 00:10:45,890 $2, which will come out that way, arg2. 162 00:10:45,890 --> 00:10:50,080 So those symbols are available to refer to arguments, 163 00:10:50,080 --> 00:10:52,390 and those apply to all of the shells. 164 00:10:52,390 --> 00:10:56,520 In addition, there are other characters. 165 00:10:56,520 --> 00:11:01,700 $* refers to the entire argument list, all of them. 166 00:11:01,700 --> 00:11:05,390 $# refers to the number of arguments. 167 00:11:05,390 --> 00:11:07,910 Again, this applies to all the shells. 168 00:11:07,910 --> 00:11:15,540 Those symbols, * and #, can be used with those meanings in other places also. 169 00:11:15,540 --> 00:11:17,940 We won't be getting into that. 170 00:11:17,940 --> 00:11:20,460 >> Shell specifier line. What's that for? 171 00:11:20,460 --> 00:11:27,760 Let's say you've written a script and it's for a particular shell and you want to run it. 172 00:11:27,760 --> 00:11:33,500 How do you know what shell your operating system will use to run your script? 173 00:11:33,500 --> 00:11:37,230 At one point you could assume that it would run it in the Bourne shell 174 00:11:37,230 --> 00:11:39,440 if you didn't say otherwise, 175 00:11:39,440 --> 00:11:41,730 but people aren't writing scripts in the Bourne shell that much anymore 176 00:11:41,730 --> 00:11:43,750 and you can't even rely on that anymore. 177 00:11:43,750 --> 00:11:48,740 So here we have a shell specifier line right here. 178 00:11:48,740 --> 00:11:52,450 That specifies Bash. 179 00:11:52,450 --> 00:11:56,750 Note that it specifies it in the pathname, /bin/bash. 180 00:11:56,750 --> 00:12:02,870 If a computer has the Bash shell but not in the bin directory, /bin, this won't work. 181 00:12:02,870 --> 00:12:06,870 That's another qualifier, another caution here. 182 00:12:06,870 --> 00:12:09,500 The pound sign is the comment line character. 183 00:12:09,500 --> 00:12:12,300 That applies to all shells. 184 00:12:12,300 --> 00:12:18,610 The particular case here, #! at the beginning of a script, is a special case. 185 00:12:18,610 --> 00:12:23,410 That specifies the shell in which to run the script. 186 00:12:23,410 --> 00:12:30,230 As I was saying, it might not be the same place/bin. 187 00:12:30,230 --> 00:12:34,880 In addition, there's another thing here. 188 00:12:34,880 --> 00:12:41,250 If you just use the pound sign with no exclamation point and pathname, 189 00:12:41,250 --> 00:12:44,640 that should indicate a C-shell. 190 00:12:44,640 --> 00:12:48,300 However, I don't recommend doing that because I'm not able to guarantee 191 00:12:48,300 --> 00:12:49,750 that that will always work. 192 00:12:49,750 --> 00:12:52,220 If you want a C-shell, it would be better to say so. 193 00:12:52,220 --> 00:12:58,450 Then there's something rather confusing here. 194 00:12:58,450 --> 00:13:03,940 If you use a shell specifier line such as /bin/bash 195 00:13:03,940 --> 00:13:07,070 and that shell is not available there, 196 00:13:07,070 --> 00:13:10,680 there's no such thing as /bin/bash on that particular computer, 197 00:13:10,680 --> 00:13:14,330 either because it doesn't have Bash or because it's in a different location, 198 00:13:14,330 --> 00:13:17,450 you'll get an error telling you that the script you ran doesn't exist. 199 00:13:17,450 --> 00:13:21,510 And of course your script exists, so that error message is confusing. 200 00:13:21,510 --> 00:13:24,810 The reason that the operating system gives you that error 201 00:13:24,810 --> 00:13:28,370 or, more accurately, that your interactive shell in which you are running this gives that error, 202 00:13:28,370 --> 00:13:33,510 is that it reports the command you used, which is the name of the script. 203 00:13:33,510 --> 00:13:36,920 That command effectively called the shell by the name of the script. 204 00:13:36,920 --> 00:13:39,330 That's where you get that confusing error message. 205 00:13:39,330 --> 00:13:42,980 Another way to call shell script 206 00:13:42,980 --> 00:13:45,910 is by specifying the shell on the command line, as here. 207 00:13:45,910 --> 00:13:52,510 This is a command. This says run Bash and then run my script in Bash. 208 00:13:52,510 --> 00:13:55,680 That will take precedence over a specifier line, 209 00:13:55,680 --> 00:14:02,090 and this has the feature of allowing you to provide for varying pathnames. 210 00:14:02,090 --> 00:14:04,840 If you just give a command, the operating system will look for that command 211 00:14:04,840 --> 00:14:06,410 in various places. 212 00:14:06,410 --> 00:14:08,820 If it's available, it should find it. 213 00:14:08,820 --> 00:14:12,290 The computer will find Bash wherever it's located and run it, 214 00:14:12,290 --> 00:14:15,470 so you don't need then to be concerned about where it finds it. 215 00:14:15,470 --> 00:14:17,360 There are potentially other concerns here, 216 00:14:17,360 --> 00:14:20,830 as if there's more than 1 version of Bash, which is possible although unlikely. 217 00:14:20,830 --> 00:14:23,540 So that's another way to deal with these things. 218 00:14:23,540 --> 00:14:30,480 Specifier lines can call any shell. 219 00:14:30,480 --> 00:14:34,480 They can also call things other than shells. 220 00:14:34,480 --> 00:14:37,940 Examples I have here are sed, which is the stream editor; 221 00:14:37,940 --> 00:14:39,900 awk, which is a pattern processing language; 222 00:14:39,900 --> 00:14:43,680 and perl, a very highly developed scripting language. 223 00:14:43,680 --> 00:14:47,570 If you put a specifier line indicating one of those programs at the beginning, 224 00:14:47,570 --> 00:14:51,270 it will go directly into that program rather than starting a shell. 225 00:14:51,270 --> 00:14:54,030 Those programs have limits to their abilities. 226 00:14:54,030 --> 00:14:58,790 Perl is very capable. Sed is an editor. It can do things beyond simply editing. 227 00:14:58,790 --> 00:15:03,300 But it can be difficult to program that. 228 00:15:03,300 --> 00:15:09,670 In addition, passing arguments and stuff to script is either impossible or confusing. 229 00:15:09,670 --> 00:15:15,030 So in those cases, with awk or sed, it's, at least in my experience, 230 00:15:15,030 --> 00:15:18,910 preferable to write a shell script and call awk or sed from the shell script 231 00:15:18,910 --> 00:15:24,660 rather than calling awk or sed as the script specifier line. 232 00:15:24,660 --> 00:15:26,980 Perl is a highly diversified language, as I said. 233 00:15:26,980 --> 00:15:30,050 You can't run interactive commands in perl, 234 00:15:30,050 --> 00:15:32,660 which means that you can't test parts of scripts that you're developing 235 00:15:32,660 --> 00:15:33,970 by running them interactively. 236 00:15:33,970 --> 00:15:36,160 However, it's an extremely capable language 237 00:15:36,160 --> 00:15:40,960 and has developed into a very widely used tool. 238 00:15:40,960 --> 00:15:45,720 That's just a little bit of a parenthetical remark about the specifier lines. 239 00:15:45,720 --> 00:15:50,610 >> In all or most forms of Linux--again, I can't be certain that's all-- 240 00:15:50,610 --> 00:15:57,900 and in Mac OS, if you type csh you get tcsh, 241 00:15:57,900 --> 00:16:00,570 and if you type sh you get bash. 242 00:16:00,570 --> 00:16:05,020 They were trying there to give you the more advanced versions of these shells, 243 00:16:05,020 --> 00:16:07,940 but this can be confusing. 244 00:16:07,940 --> 00:16:16,720 If you write a script using tcsh or Bash features while calling csh or sh 245 00:16:16,720 --> 00:16:22,230 and then try to run it on a computer which doesn't have tcsh or Bash, 246 00:16:22,230 --> 00:16:25,050 you might get some errors if there are commands in there 247 00:16:25,050 --> 00:16:27,970 which those shells don't recognize. 248 00:16:27,970 --> 00:16:34,120 In addition, you may have called up your shell on your local computer 249 00:16:34,120 --> 00:16:37,700 calling it as sh or csh and then getting the more advanced shells. 250 00:16:37,700 --> 00:16:41,440 You may not even think of the fact that you're using the more advanced shell. 251 00:16:41,440 --> 00:16:45,670 So this is a potential pitfall. 252 00:16:45,670 --> 00:16:50,290 How is it established that if you type sh you get Bash, 253 00:16:50,290 --> 00:16:55,580 if you type csh you get tsch? 254 00:16:55,580 --> 00:16:59,940 There are things in these computers called links 255 00:16:59,940 --> 00:17:06,460 which can connect to file names to refer to the same thing. 256 00:17:06,460 --> 00:17:12,180 It can either be 2 names for the same file or a file whose purpose is to refer to another file. 257 00:17:12,180 --> 00:17:17,550 They're called hard and symbolic links. We won't be going into that anymore today. 258 00:17:17,550 --> 00:17:21,619 There may also be separate files--1 file sh, 1 file Bash-- 259 00:17:21,619 --> 00:17:23,880 but they both run Bash. 260 00:17:23,880 --> 00:17:29,350 Then there's another qualifier here. 261 00:17:29,350 --> 00:17:42,640 If you're calling one of these shells by one name, 262 00:17:42,640 --> 00:17:46,640 you might think you'd get the same functionality as calling it by another name. 263 00:17:46,640 --> 00:17:49,700 Well, that actually isn't necessarily true. 264 00:17:49,700 --> 00:17:55,020 These commands can examine the name by which they were called 265 00:17:55,020 --> 00:18:00,020 and they can, on the basis of that name, behave differently. 266 00:18:00,020 --> 00:18:02,740 There may be issues of trying to conform to a standard. 267 00:18:02,740 --> 00:18:06,060 Some of you may have heard of the POSIX standard or another, 268 00:18:06,060 --> 00:18:08,730 maybe other features. 269 00:18:08,730 --> 00:18:14,520 This can be selected sometimes by command line arguments 270 00:18:14,520 --> 00:18:17,310 or by setting shell variables. 271 00:18:17,310 --> 00:18:22,170 Calling it as sh or bash may actually lead to a different execution 272 00:18:22,170 --> 00:18:25,300 even if it's the same file that you're executing. 273 00:18:25,300 --> 00:18:31,800 Another thing to consider is that even if another computer has tcsh or Bash, 274 00:18:31,800 --> 00:18:35,310 if they aren't linked as they are on your local computer 275 00:18:35,310 --> 00:18:37,990 if you have a Linux or Mac OS local computer, 276 00:18:37,990 --> 00:18:45,630 then again you'll get the shell that you call sh or csh, not the one that you might prefer. 277 00:18:50,430 --> 00:19:01,130 The current Bourne shell has enhancements lesser than those in Bash 278 00:19:01,130 --> 00:19:06,100 but past those in the original Bourne shell. 279 00:19:06,100 --> 00:19:09,690 As a result of that, even the current Bourne shell, sh, 280 00:19:09,690 --> 00:19:14,560 even when it's not Bash, resembles the C language more than the C-shell does. 281 00:19:14,560 --> 00:19:20,460 That wasn't true when the C-shell was first created, but it has developed that way. 282 00:19:20,460 --> 00:19:26,560 You might notice here that all these shell names except for the Bourne shell 283 00:19:26,560 --> 00:19:30,640 have something to indicate which shell they are--csh, bash-- 284 00:19:30,640 --> 00:19:32,550 but the Bourne shell is just sh. 285 00:19:32,550 --> 00:19:34,910 Why? That was the original shell. 286 00:19:34,910 --> 00:19:37,770 It was THE shell then, not A shell, 287 00:19:37,770 --> 00:19:41,090 and since it was THE shell, there was no reason to distinguish it from another shell. 288 00:19:41,090 --> 00:19:45,030 So that's why it has that name and still does. 289 00:19:50,630 --> 00:19:58,990 >> This top here is a line from a password database for an account I have there 290 00:19:58,990 --> 00:20:01,680 on another computer. 291 00:20:01,680 --> 00:20:08,300 I'm going to try to get that name so you can see that part at the end, the shell. 292 00:20:09,720 --> 00:20:15,450 The password database holds the login characteristics for all the users. 293 00:20:15,450 --> 00:20:20,330 At the beginning is the username, which you can see the last 2 letters of mine now. 294 00:20:20,330 --> 00:20:23,970 The fields here are separated by colons. 295 00:20:23,970 --> 00:20:28,210 The last field, as you can see, is bin/tcsh, the shell. 296 00:20:28,210 --> 00:20:30,230 That's the shell specifier. 297 00:20:30,230 --> 00:20:33,240 There's something interesting here. 298 00:20:33,240 --> 00:20:36,950 When Unix was first developed, there was only 1 shell, 299 00:20:36,950 --> 00:20:38,350 so there was no choice there. 300 00:20:38,350 --> 00:20:45,570 So why did they allow a field in the password database to specify a shell? 301 00:20:45,570 --> 00:20:47,920 I don't know, but it's fortunate that they did. 302 00:20:47,920 --> 00:20:52,030 It's rather difficult to make changes in the password database format 303 00:20:52,030 --> 00:20:54,420 because many programs refer to its format 304 00:20:54,420 --> 00:20:57,720 and would have to be rewritten. 305 00:20:57,720 --> 00:21:04,130 It's a felicitous or fortuitous development that they included that field. 306 00:21:04,130 --> 00:21:12,780 That kind of a password file line is used on all Unix and Linux computers so far as I know. 307 00:21:12,780 --> 00:21:14,650 The Mac has its own system. 308 00:21:14,650 --> 00:21:17,810 It actually has a password file with the lines in that format, 309 00:21:17,810 --> 00:21:21,060 but that isn't where the user characteristics are defined. 310 00:21:21,060 --> 00:21:24,200 Another parenthetical remark there. 311 00:21:36,470 --> 00:21:46,020 >> If you're calling a shell, you can call it as a sub-shell of your existing shells. 312 00:21:46,020 --> 00:21:50,480 So if I go here, let's get rid of these things. 313 00:21:50,480 --> 00:21:53,350 Here I am in the C-shell. 314 00:21:56,830 --> 00:22:01,200 That variable, which accurately identifies my shell, 315 00:22:01,200 --> 00:22:04,300 actually isn't always a reliable way of determining what shell you're running, 316 00:22:04,300 --> 00:22:06,220 but in this case it is. 317 00:22:06,220 --> 00:22:08,040 What if I just type-- 318 00:22:09,970 --> 00:22:12,470 Now I'm in Bash. 319 00:22:12,470 --> 00:22:19,540 Some things are going to be the same. ls tells me my commands. 320 00:22:19,540 --> 00:22:24,500 If I do a suspend back to my C-shell, ls, same. Right? 321 00:22:24,500 --> 00:22:28,890 fg, foreground, back to my Bash shell. 322 00:22:28,890 --> 00:22:38,290 pwd, current directory, back to the C-shell. 323 00:22:38,290 --> 00:22:43,180 pwd, different directory--actually not a different directory in this case. 324 00:22:43,180 --> 00:22:45,110 It's the same directory. 325 00:22:45,110 --> 00:22:50,000 Let's say I want to call a command here: where ls. 326 00:22:50,000 --> 00:22:52,140 What does that do? 327 00:22:52,140 --> 00:22:53,670 It tells me where the ls command, 328 00:22:53,670 --> 00:22:56,670 the one that gives me a directory listing, is located in ls. 329 00:22:56,670 --> 00:23:01,460 Let's go back to Bash shell. Let's try the same thing. 330 00:23:01,460 --> 00:23:05,830 Hmm, interesting there, where: command not found. 331 00:23:05,830 --> 00:23:07,400 Why is that? 332 00:23:07,400 --> 00:23:11,570 The where command is built in to the C-shell. 333 00:23:11,570 --> 00:23:15,630 This isn't a command that has to be read in to memory from somewhere else and executed. 334 00:23:15,630 --> 00:23:20,310 The C-shell runs it by transferring execution to part of its own code 335 00:23:20,310 --> 00:23:22,790 and it's not in the Bash shell. 336 00:23:22,790 --> 00:23:25,710 So Bash, not having such a built-in command, looks for it, doesn't find it, 337 00:23:25,710 --> 00:23:27,720 and we get an error. 338 00:23:27,720 --> 00:23:32,290 So there we have a Bash shell running under a C-shell, and we call that a sub-shell. 339 00:23:32,290 --> 00:23:38,480 And just in case you're curious, Bash shell has its own way of locating commands. 340 00:23:38,480 --> 00:23:42,590 hashed refers to the fact that it can be executed more rapidly, 341 00:23:42,590 --> 00:23:44,960 being found more rapidly. 342 00:23:44,960 --> 00:23:48,610 That's one of the enhancements built in to some of these shells. 343 00:23:50,220 --> 00:23:54,200 >> Bourne-type shells are preferred for programming. 344 00:23:54,200 --> 00:23:57,300 They have control structures like loops, conditional statements, 345 00:23:57,300 --> 00:24:00,240 the sort of commands that you might use in programming languages like C 346 00:24:00,240 --> 00:24:04,190 or whatever language. Maybe you're programming in Java or whatever. 347 00:24:04,190 --> 00:24:06,460 Shells have those too. 348 00:24:06,460 --> 00:24:11,790 The Bourne-type shells, particularly Bash, have more 349 00:24:11,790 --> 00:24:15,730 and they are designed with greater flexibility. 350 00:24:15,730 --> 00:24:20,700 The Bash shell has arrays. The original Bourne shell doesn't. 351 00:24:20,700 --> 00:24:26,130 So that can be considerably advantageous for programming. 352 00:24:26,130 --> 00:24:29,810 The C-shell actually does have arrays but doesn't have a lot of these other features. 353 00:24:29,810 --> 00:24:33,450 The Bourne-type shells will execute faster 354 00:24:33,450 --> 00:24:36,520 if they don't have the features intended for interactive use. 355 00:24:36,520 --> 00:24:39,340 You load things down for one purpose; this loads them down for another purpose. 356 00:24:39,340 --> 00:24:41,520 There's that trade-off there. 357 00:24:41,520 --> 00:24:44,510 Those features which are intended for interactive use 358 00:24:44,510 --> 00:24:46,920 really are of little or no use for scripting. 359 00:24:46,920 --> 00:24:52,160 It's possible to use an interactive sub-shell just like the one I started there 360 00:24:52,160 --> 00:24:57,780 to test out commands which you intend to use in a script. 361 00:24:57,780 --> 00:25:01,180 That's what you can't do with perl. You can do it with the shells. 362 00:25:01,180 --> 00:25:04,850 Even the structures like for loops and so forth can be run interactively. 363 00:25:04,850 --> 00:25:07,000 They are occasionally useful to run interactively, 364 00:25:07,000 --> 00:25:10,180 but more likely you're using them to develop a script. 365 00:25:15,690 --> 00:25:17,400 >> Aliases. 366 00:25:17,400 --> 00:25:21,630 This is going to be about the C-shell. 367 00:25:23,270 --> 00:25:27,570 History mechanism where you get back to earlier commands 368 00:25:27,570 --> 00:25:30,340 or parts of them that you've already run. 369 00:25:30,340 --> 00:25:33,680 Again, about the C-shell, the Bourne shell and the Korn shell have these things, 370 00:25:33,680 --> 00:25:35,620 but I'm not going to get into them. 371 00:25:35,620 --> 00:25:40,340 So here are some useful aliases that I have. 372 00:25:43,100 --> 00:25:44,880 Instead of typing ls--it's a common command-- 373 00:25:44,880 --> 00:25:47,620 just type l and save yourself 1 character. 374 00:25:47,620 --> 00:25:50,600 ls with various options, all those work. 375 00:25:50,600 --> 00:25:54,460 Note that those definitions have quotes around them. 376 00:25:54,460 --> 00:25:57,520 In these cases, the quotes aren't necessary. 377 00:25:57,520 --> 00:26:00,100 If you can define those aliases without the quotes, it would still work. 378 00:26:00,100 --> 00:26:02,910 They are recommended. 379 00:26:02,910 --> 00:26:04,900 There are situations in which you can't use the quote 380 00:26:04,900 --> 00:26:08,050 because you want something to happen which the quote would prevent. 381 00:26:08,050 --> 00:26:11,210 Sometimes you can quote part of the definition but not all of it. 382 00:26:11,210 --> 00:26:17,010 It's also generally recommended to use single quotes rather than double quotes. 383 00:26:17,010 --> 00:26:19,750 Double quotes have effects on variable definitions, 384 00:26:19,750 --> 00:26:22,950 particularly causing them to be evaluated rather than stopping it. 385 00:26:22,950 --> 00:26:25,910 Why would we want to stop the evaluation? 386 00:26:25,910 --> 00:26:28,710 And how do quotes do that for us? 387 00:26:28,710 --> 00:26:32,600 >> Here is a command which you might find interesting. 388 00:26:32,600 --> 00:26:35,470 'ls g*' 389 00:26:35,470 --> 00:26:37,640 g*, as you probably know, is a wildcard expression 390 00:26:37,640 --> 00:26:40,290 for all the file names beginning with g. 391 00:26:40,290 --> 00:26:46,410 If I just write in a command ls g*, I'll get a list of all those names in my current directory. 392 00:26:46,410 --> 00:26:50,870 If I define that alias as it is here with the quotes, 393 00:26:50,870 --> 00:26:56,990 it will run that command in your current directory where you're running it. 394 00:26:56,990 --> 00:27:01,250 But if you run the alias definition without the quotes, 395 00:27:01,250 --> 00:27:09,620 it will evaluate the wildcard g* when it runs this defining command. 396 00:27:09,620 --> 00:27:14,400 So the definition of the alias will be ls followed by the list of files in the directory 397 00:27:14,400 --> 00:27:16,310 in which the alias command is executed, 398 00:27:16,310 --> 00:27:19,180 regardless of where you actually intend to run the command. 399 00:27:19,180 --> 00:27:26,360 This isn't of much use, and the single quotes prevent the evaluation of the asterisk. 400 00:27:26,360 --> 00:27:30,780 So you just get the definition being ls g*. 401 00:27:30,780 --> 00:27:35,510 Then when you run the alias, lgs, it then puts that out. 402 00:27:35,510 --> 00:27:40,490 Now there are no quotes, and it will evaluate the asterisk when you run the alias command. 403 00:27:40,490 --> 00:27:43,900 So that's one thing. 404 00:27:43,900 --> 00:27:46,590 Double quotes would have that same effect here, 405 00:27:46,590 --> 00:27:50,580 but there are other cases in which double quotes wouldn't work so well. 406 00:27:50,580 --> 00:27:52,450 >> Here is another one. 407 00:27:52,450 --> 00:27:54,270 You might know the grep command. 408 00:27:54,270 --> 00:28:02,110 The grep command can be used to scan a file for lines which have certain strings. 409 00:28:02,110 --> 00:28:10,350 So let's go over here and I'll exit from my Bourne shell. 410 00:28:23,570 --> 00:28:25,450 Okay. Here's a file. 411 00:28:25,450 --> 00:28:31,490 Let's say it's grep abc strings. There it is. 412 00:28:31,490 --> 00:28:37,930 If I do grep zddd, I get nothing. Okay. 413 00:28:37,930 --> 00:28:40,960 So it finds a string, it reports; it doesn't find, it doesn't report it. 414 00:28:40,960 --> 00:28:44,930 It outputs any line which has that string on it. 415 00:28:44,930 --> 00:28:49,080 There are all sorts of options here which you can find in the documentation. 416 00:28:49,080 --> 00:28:52,160 Here's one way to do it. 417 00:28:52,160 --> 00:29:03,290 What about this one, alias grabc 'grep abc'? 418 00:29:03,290 --> 00:29:09,000 That's going to include 1 argument when the alias is defined. 419 00:29:09,000 --> 00:29:26,300 So if I do that here, now if I do grabc, 420 00:29:26,300 --> 00:29:30,620 now the alias includes more than the simple command. It also has the argument. 421 00:29:30,620 --> 00:29:32,190 So far that works. 422 00:29:32,190 --> 00:29:38,590 I have another command here, this one, so those are different strings in there 423 00:29:38,590 --> 00:29:46,790 and show that this doesn't find anything there since it doesn't match. 424 00:29:46,790 --> 00:29:56,180 >> What if I want to include in the alias definition the file that I'm going to search 425 00:29:56,180 --> 00:30:02,970 and I want to give as an argument to the alias the string that I'm looking for? 426 00:30:02,970 --> 00:30:08,040 I might want to say abc as the argument to my alias, 427 00:30:08,040 --> 00:30:10,870 but the alias already determined the file. 428 00:30:10,870 --> 00:30:15,710 And that's where this expression comes in. 429 00:30:20,430 --> 00:30:25,270 Notice here we have grep just like before. 430 00:30:25,270 --> 00:30:28,130 We have the file here, strings. 431 00:30:28,130 --> 00:30:35,610 \!^, kind of an odd expression, I suppose, if you haven't seen this before. 432 00:30:35,610 --> 00:30:39,920 Exclamation point is part of the C-shell history mechanism. 433 00:30:39,920 --> 00:30:45,220 It can recall earlier commands, it can recall arguments to those commands and so forth. 434 00:30:46,760 --> 00:31:01,570 The history mechanism is used as part of aliasing. 435 00:31:01,570 --> 00:31:07,390 If you specify a line after the exclamation point, it will refer to that line in the history list, 436 00:31:07,390 --> 00:31:11,910 which we won't be getting into now since it's a whole other topic. 437 00:31:11,910 --> 00:31:16,280 It is possible to specify part of a line. 438 00:31:16,280 --> 00:31:22,950 So !3:2 would be the second argument of command number 3. 439 00:31:22,950 --> 00:31:30,430 The caret here in this expression stands for the first argument. 440 00:31:30,430 --> 00:31:34,410 If you don't give it an indication of which command you're referring to, 441 00:31:34,410 --> 00:31:37,300 it refers to the immediately previous command, 442 00:31:37,300 --> 00:31:41,990 and the caret is a symbol for the first argument. 443 00:31:41,990 --> 00:31:46,820 Because it's the caret and not the number, you don't need to use the colon, 444 00:31:46,820 --> 00:31:52,660 so !^ means the first argument to the previous command. 445 00:31:52,660 --> 00:31:55,020 A little mixed up here. 446 00:31:55,020 --> 00:31:58,450 In this case, when you use this as an alias definition, 447 00:31:58,450 --> 00:32:04,650 the history reference refers back to the commands in which the alias is used. 448 00:32:04,650 --> 00:32:08,470 So this is going back 1 command as a history operation, 449 00:32:08,470 --> 00:32:11,810 but as an alias operation it refers to the command in which you would type, 450 00:32:11,810 --> 00:32:14,780 say, grstrings_file. 451 00:32:17,440 --> 00:32:20,240 We have the quotes here in it. What's the backslash for? 452 00:32:20,240 --> 00:32:30,810 In this case, as elsewhere, we don't want to execute the history mechanism 453 00:32:30,810 --> 00:32:33,680 while defining the alias. 454 00:32:33,680 --> 00:32:37,900 If we didn't have the backslash there, the shell would pull in the first argument 455 00:32:37,900 --> 00:32:41,870 of the command right before it ran this alias command, which we don't want. 456 00:32:41,870 --> 00:32:47,520 We want this to be built in to the alias command to call in an argument later. 457 00:32:47,520 --> 00:32:53,550 Single quotes don't escape an exclamation point, the history reference. 458 00:32:53,550 --> 00:32:57,450 Maybe you know the expression escape means to change the meaning of something. 459 00:32:57,450 --> 00:33:00,260 In this case, it means to stop something from having a special meaning. 460 00:33:00,260 --> 00:33:03,030 Exclamation point's special meaning is history. 461 00:33:03,030 --> 00:33:05,790 Escape and it doesn't have that meaning. 462 00:33:05,790 --> 00:33:08,080 Quotes don't do that; backslash does. 463 00:33:08,080 --> 00:33:11,900 So we're actually using 2 levels of escaping here. 464 00:33:23,500 --> 00:33:29,620 I'm going to move this command into the other window without typing it 465 00:33:29,620 --> 00:33:35,210 by using these editing operations, which you may find useful. 466 00:33:40,620 --> 00:33:42,460 Something else here I'll show you. 467 00:33:42,460 --> 00:33:46,730 If you just type alias with no arguments, it tells you all your arguments. 468 00:33:46,730 --> 00:33:48,640 This is a bunch of aliases I already had here 469 00:33:48,640 --> 00:33:53,400 besides those that I have been using here today. 470 00:33:53,400 --> 00:34:00,220 But if I just type with the name of an alias, it tells me what it means. 471 00:34:00,220 --> 00:34:03,390 Notice that the quotes are gone and the backslash is gone. 472 00:34:03,390 --> 00:34:08,620 This string here is the result of that alias definition, 473 00:34:08,620 --> 00:34:12,199 and now it has just !^ in it. 474 00:34:12,199 --> 00:34:19,150 This is going to look in the file strings for anything. 475 00:34:19,150 --> 00:34:34,900 So if I do grstrings_file strings, I didn't give it anything to look for there, 476 00:34:34,900 --> 00:34:37,429 but it's looking in strings. 477 00:34:37,429 --> 00:34:42,330 It didn't find the word strings in the file strings, but it does find abc. 478 00:34:42,330 --> 00:34:46,770 And it doesn't find that. 479 00:34:46,770 --> 00:34:52,330 So here we are giving an argument that hits into the definition of the alias, 480 00:34:52,330 --> 00:34:55,530 that is inserted into it. 481 00:34:55,530 --> 00:34:58,540 It's where this expression comes from. 482 00:34:58,540 --> 00:35:00,240 You can use more than 1. 483 00:35:00,240 --> 00:35:03,170 The caret is a symbol for the first argument. 484 00:35:03,170 --> 00:35:07,510 If you wanted to use a second argument, you would then say :2. 485 00:35:07,510 --> 00:35:11,250 There's no special symbol for the second argument. 486 00:35:11,250 --> 00:35:14,790 And because you're using a numeral, you would have to use the colon. 487 00:35:14,790 --> 00:35:17,220 There is, however, another choice here. 488 00:35:17,220 --> 00:35:21,220 The dollar sign stands for the last argument. 489 00:35:21,220 --> 00:35:23,320 And because this is a symbol, you can omit the colon. 490 00:35:23,320 --> 00:35:25,870 So it would be the last argument in the list. 491 00:35:25,870 --> 00:35:27,900 And there's also that one. 492 00:35:27,900 --> 00:35:31,380 Asterisk means all of, so this is the complete argument list, 493 00:35:31,380 --> 00:35:35,150 and again, you can omit the colon because it's not a numeral. 494 00:35:36,970 --> 00:35:39,950 I hope you're all observing all this. 495 00:35:39,950 --> 00:35:54,100 >> The history mechanism can go back to earlier lines in the history list. 496 00:35:54,100 --> 00:36:01,370 You could do this in an alias definition. 497 00:36:01,370 --> 00:36:02,950 I've never seen this done. 498 00:36:02,950 --> 00:36:05,840 It would have the effect of pulling out earlier commands from the history list 499 00:36:05,840 --> 00:36:08,130 when you execute the alias, which could be different commands 500 00:36:08,130 --> 00:36:11,240 depending on when and where you execute it. 501 00:36:11,240 --> 00:36:14,020 Conceivably you might want to pull out such a reference 502 00:36:14,020 --> 00:36:15,900 just to know what an earlier command was. 503 00:36:15,900 --> 00:36:17,280 I've never seen this happen. 504 00:36:17,280 --> 00:36:19,970 I suppose somebody might want to, but this is very unlikely. 505 00:36:19,970 --> 00:36:26,480 There is another thing here. 506 00:36:26,480 --> 00:36:33,060 If you use that history-type reference, 507 00:36:33,060 --> 00:36:38,190 then only the arguments to which there is such a reference are used. 508 00:36:38,190 --> 00:36:42,180 If you have an alias definition which doesn't use a history-type reference, 509 00:36:42,180 --> 00:36:44,060 if it just becomes the beginning of the command 510 00:36:44,060 --> 00:36:46,520 and you have further arguments, then anything you type after that 511 00:36:46,520 --> 00:36:48,450 will be added to the command. 512 00:36:48,450 --> 00:36:52,040 In this case, the example I just gave there, we used the first argument; 513 00:36:52,040 --> 00:36:54,610 we didn't use any others. 514 00:36:54,610 --> 00:36:57,960 If other arguments had been given on the command line, they would not be used. 515 00:36:57,960 --> 00:37:04,630 So if you use the history reference at all, then you must use it to get any argument. 516 00:37:04,630 --> 00:37:11,310 >> There's another thing here I just want to mention, partly parenthetically, 517 00:37:11,310 --> 00:37:15,250 namely that this history mechanism with the exclamation point 518 00:37:15,250 --> 00:37:18,010 goes back to the original C-shell. 519 00:37:18,010 --> 00:37:27,060 The tcsh introduced history operations 520 00:37:27,060 --> 00:37:30,910 which use the sorts of commands and strings from the editors, 521 00:37:30,910 --> 00:37:33,650 either Emacs or vi. 522 00:37:33,650 --> 00:37:36,430 My personal opinion is Emacs is much easier to use for this purpose 523 00:37:36,430 --> 00:37:39,390 even if you use vi for your regular editing. 524 00:37:39,390 --> 00:37:43,900 There are various Emacs commands which are now adapted for history. 525 00:37:43,900 --> 00:37:46,410 Control P gets the previous line in the history list. 526 00:37:46,410 --> 00:37:48,840 Another Control P will get you the one before that. 527 00:37:48,840 --> 00:37:50,540 The up arrow does the same thing. 528 00:37:50,540 --> 00:37:54,190 Control N gets the next command if you've already scrolled back some ways. 529 00:37:54,190 --> 00:37:55,880 Down arrow does that too. 530 00:37:55,880 --> 00:38:00,480 You can move left to right with the arrows and various other things. 531 00:38:00,480 --> 00:38:02,390 This can make use of the history mechanism 532 00:38:02,390 --> 00:38:05,070 much easier than using the exclamation point syntax, 533 00:38:05,070 --> 00:38:07,930 but you wouldn't use that in an alias definition. 534 00:38:17,780 --> 00:38:20,020 We'll go over that some other time. 535 00:38:24,300 --> 00:38:25,810 >> Variables. 536 00:38:26,880 --> 00:38:29,510 You know what variables are in programming languages. 537 00:38:29,510 --> 00:38:31,680 The shells have them also. 538 00:38:31,680 --> 00:38:37,350 The C-shell uses the command set to assign variables, 539 00:38:37,350 --> 00:38:41,360 so that sets the variable a to the value of b-- 540 00:38:41,360 --> 00:38:46,390 as I said, a useless definition but an illustration of how this is used. 541 00:38:48,790 --> 00:38:52,410 The set command will create a variable if it doesn't already exist. 542 00:38:55,270 --> 00:39:02,490 The positional parameters for shell scripts can be considered variables, 543 00:39:02,490 --> 00:39:10,750 but the use of them and the rules for them are somewhat different. 544 00:39:10,750 --> 00:39:14,320 You can't assign a value to $1 in the course of a script. 545 00:39:14,320 --> 00:39:18,340 You would have to define a new variable for that purpose if some of you wanted to. 546 00:39:23,000 --> 00:39:28,470 Type set with no arguments and you get a list of all the currently defined variables. 547 00:39:28,470 --> 00:39:34,220 And let's get over to my other shell here and see what we get if we do that. 548 00:39:34,220 --> 00:39:37,110 Quite a long list there, right? 549 00:39:37,110 --> 00:39:40,990 Scroll up a little bit. Look at all that. 550 00:39:40,990 --> 00:39:44,330 Some of these things are defined automatically by the shell. 551 00:39:44,330 --> 00:39:49,320 The shell creates the variable and gives it a value. 552 00:39:49,320 --> 00:39:52,730 Some of them are defined by the shell but then redefined by the user 553 00:39:52,730 --> 00:39:54,820 according to his preferences. 554 00:39:54,820 --> 00:39:59,110 And some of them are created by the user depending on what he's doing that day. 555 00:39:59,110 --> 00:40:01,880 That's just set with no arguments. 556 00:40:06,920 --> 00:40:10,050 There's an odd feature here of this thing. 557 00:40:10,050 --> 00:40:17,980 There have to be either no spaces between the equals sign and the variable name 558 00:40:17,980 --> 00:40:23,700 and the value or spaces on both sides of the equals sign, 559 00:40:23,700 --> 00:40:28,940 as in this one. 560 00:40:35,620 --> 00:40:41,340 This won't work, and this actually is a valid command 561 00:40:41,340 --> 00:40:43,390 but it won't do what you intend. 562 00:40:43,390 --> 00:40:50,070 That command will work because if you just say set and a variable name 563 00:40:50,070 --> 00:40:54,890 with no equals sign or set and a variable name with an equals sign and no value, 564 00:40:54,890 --> 00:40:57,770 it will set the variable to a null value. 565 00:40:57,770 --> 00:41:00,120 So set a= is a valid command. 566 00:41:00,120 --> 00:41:04,370 The set command can define more than 1 variable on the same line. 567 00:41:04,370 --> 00:41:11,240 So this command here has the effect of defining both a and b to null values. 568 00:41:11,240 --> 00:41:13,470 Probably not what you want. 569 00:41:13,470 --> 00:41:17,940 This one here, mentioned earlier, will lead to an error 570 00:41:17,940 --> 00:41:21,270 because =b is not a valid expression. 571 00:41:21,270 --> 00:41:23,680 A variable name can't begin with the equals sign. 572 00:41:26,760 --> 00:41:29,080 And there are these further things here. 573 00:41:29,080 --> 00:41:36,820 The colons were used to select arguments from history lines, 574 00:41:36,820 --> 00:41:41,210 and they can be used--and I didn't go into before--to modify those things. 575 00:41:41,210 --> 00:41:44,480 They can also be used to modify shell variables. 576 00:41:44,480 --> 00:41:49,050 This one here, $a, has a value. 577 00:41:49,050 --> 00:41:55,040 :r will take off an extension. 578 00:41:55,040 --> 00:41:57,200 An extension will be anything following a dot, 579 00:41:57,200 --> 00:41:59,200 a dot and anything following it at the end of a file, 580 00:41:59,200 --> 00:42:03,230 only at the end of the list after the last slash. 581 00:42:03,230 --> 00:42:05,480 So I have it here. 582 00:42:05,480 --> 00:42:10,730 a is that. It will drop the .o. 583 00:42:10,730 --> 00:42:16,510 If there's no extension, only the pathnames after the last slash, it will have no effect. 584 00:42:16,510 --> 00:42:27,480 a:h, that variable expression, will take off the last element of a directory list, 585 00:42:27,480 --> 00:42:29,660 again, only after the last slash. 586 00:42:29,660 --> 00:42:33,160 So /a/b/c becomes /a/b, 587 00:42:33,160 --> 00:42:38,870 but this one is changed because the element after the list is null. 588 00:42:38,870 --> 00:42:43,070 Here there is something which also I want to emphasize. 589 00:42:43,070 --> 00:42:46,770 These qualifiers don't search for the existence of these files. 590 00:42:46,770 --> 00:42:48,910 They just look for strings. 591 00:42:48,910 --> 00:42:54,520 These are intended to manipulate file names, pathnames, 592 00:42:54,520 --> 00:42:57,520 but they can be used on any string even if it's not a file name. 593 00:42:57,520 --> 00:42:58,920 And they don't look for the existence, 594 00:42:58,920 --> 00:43:03,550 so if there's no such file, /a/b/c, this will still work. 595 00:43:03,550 --> 00:43:06,930 Whether it's of any use is another question, but it will still work. 596 00:43:06,930 --> 00:43:12,850 Variables are different in the Bourne shells. We'll get to that later. 597 00:43:12,850 --> 00:43:18,240 Dollar sign can be escaped just like the exclamation point and the asterisk. 598 00:43:18,240 --> 00:43:21,760 Dollar sign can be escaped with a backslash or the single quotes. 599 00:43:21,760 --> 00:43:24,790 Double quotes have the odd effect in all shells 600 00:43:24,790 --> 00:43:28,690 of forcing the evaluation of a dollar sign variable expression. 601 00:43:28,690 --> 00:43:31,960 So if it's being escaped one way, the double quotes can have the effect 602 00:43:31,960 --> 00:43:34,380 of causing it to be evaluated anyway. 603 00:43:34,380 --> 00:43:37,090 This is a little confusing. 604 00:43:37,090 --> 00:43:43,740 If there are multiple levels of escaping, such as single quotes inside double quotes 605 00:43:43,740 --> 00:43:46,770 or double quotes inside single quotes, you should test to see what will happen 606 00:43:46,770 --> 00:43:49,520 to a variable if you're using one. 607 00:43:49,520 --> 00:43:53,410 Those 2 situations--double inside of single, single inside of double-- 608 00:43:53,410 --> 00:43:55,980 don't necessarily give you the same result. 609 00:44:02,520 --> 00:44:05,600 Environment variables, bound C-shell variables. 610 00:44:05,600 --> 00:44:08,340 Environment variables are also variables in the C-shell, 611 00:44:08,340 --> 00:44:11,250 and they are also variables in other shells too. 612 00:44:11,250 --> 00:44:15,230 In the C-shell, they are distinct sets. 613 00:44:15,230 --> 00:44:18,130 The things I was saying before are about shell variables. 614 00:44:18,130 --> 00:44:21,300 Environment variables are a distinct set of variables 615 00:44:21,300 --> 00:44:28,650 with the exception of several variables which we call bound variables, 616 00:44:28,650 --> 00:44:30,640 which are very important and we'll get into those later. 617 00:44:30,640 --> 00:44:34,950 Environment variables are automatically passed on 618 00:44:34,950 --> 00:44:41,800 to shells or commands that are run from your shell. 619 00:44:41,800 --> 00:44:46,220 The other things aren't. The shell variables, the aliases aren't. Environment variables are. 620 00:44:46,220 --> 00:44:48,630 That's why we call them environment variables, 621 00:44:48,630 --> 00:44:55,030 the idea being that the environment extends past just your current shell. 622 00:44:55,030 --> 00:45:00,510 They can be used to define things for commands. 623 00:45:00,510 --> 00:45:05,470 Here is an example. PRINTER, LPDEST. 624 00:45:05,470 --> 00:45:12,270 Both of those variables can define a printer that a command will use to print things. 625 00:45:12,270 --> 00:45:16,500 If you have multiple printers around, you might want to put the one you like. 626 00:45:16,500 --> 00:45:21,320 The reason we have 2 variables is that different sets of commands were written 627 00:45:21,320 --> 00:45:23,870 using these different variables. 628 00:45:23,870 --> 00:45:25,910 You might give them different values. 629 00:45:25,910 --> 00:45:28,860 Most likely you'll give them both the same value. 630 00:45:28,860 --> 00:45:35,840 Those things work because the commands that do printing 631 00:45:35,840 --> 00:45:40,740 were programmed to examine the values of these variables. 632 00:45:42,200 --> 00:45:46,150 If a program were not written that way, if it were written to do something else, 633 00:45:46,150 --> 00:45:48,280 the variable would be irrelevant. 634 00:45:48,280 --> 00:45:52,530 So the operating system isn't looking for these variables 635 00:45:52,530 --> 00:45:55,210 every time you refer to a printer. 636 00:45:55,210 --> 00:45:59,090 A command that does printing is looking for these variables if it is programmed that way. 637 00:46:11,030 --> 00:46:15,240 These variables are often defined in your initialization files 638 00:46:15,240 --> 00:46:19,440 but not necessarily. 639 00:46:19,440 --> 00:46:21,050 You can define them on the command line. 640 00:46:21,050 --> 00:46:24,090 They may be defined in a command. 641 00:46:24,090 --> 00:46:28,740 A command that runs something might have its own selection of variables-- 642 00:46:28,740 --> 00:46:32,390 variables that are unique to a particular software package, for example. 643 00:46:32,390 --> 00:46:36,740 They will be defined when you run that package. 644 00:46:39,690 --> 00:46:42,680 How are these variables passed to a sub-shell? 645 00:46:42,680 --> 00:46:48,210 When a sub-shell is written, it doesn't write into that area. 646 00:46:48,210 --> 00:46:53,260 The area of the sub-shell that is devoted to environment variables 647 00:46:53,260 --> 00:46:56,450 isn't written by the sub-shell; it's written by copying. 648 00:46:56,450 --> 00:47:00,530 When you run an ordinary command, such as these commands to print or whatever, 649 00:47:00,530 --> 00:47:03,840 they start off by creating a new shell. 650 00:47:03,840 --> 00:47:06,190 The shell creates a shell and then overwrites part of it 651 00:47:06,190 --> 00:47:08,800 with the command that you're running, which is a little confusing, 652 00:47:08,800 --> 00:47:10,740 but that's how these commands get the environment variables 653 00:47:10,740 --> 00:47:14,890 that they then refer to later on. 654 00:47:21,920 --> 00:47:28,010 The command here for defining the variable setenv. 655 00:47:28,010 --> 00:47:36,470 That's how you define it. It's 3 elements: setenv, variable, value. 656 00:47:36,470 --> 00:47:44,710 If you just do setenv with no arguments, what do you get? 657 00:47:47,220 --> 00:47:48,810 A list of all of those variables. 658 00:47:48,810 --> 00:47:53,190 Again, it's a nice long list and in this case, as in the others, 659 00:47:53,190 --> 00:47:57,320 these variables are defined largely by my login operation by the shell itself 660 00:47:57,320 --> 00:47:59,740 rather than by anything I did. 661 00:47:59,740 --> 00:48:03,580 There's another command here, printenv. 662 00:48:07,520 --> 00:48:10,340 That also prints out the environment. 663 00:48:10,340 --> 00:48:15,240 Notice this last thing here, EDITOR=vi. 664 00:48:15,240 --> 00:48:21,120 That says that if I'm using something that calls an editor 665 00:48:21,120 --> 00:48:25,530 and I don't specify an editor and it allows me the choice, it may give me vi. 666 00:48:25,530 --> 00:48:37,280 What if I do printenv EDITOR? It tells me what it is. 667 00:48:37,280 --> 00:48:41,340 Right before that, there was a variable, LESS. 668 00:48:41,340 --> 00:48:46,040 These are your defaults options when I run the LESS command, 669 00:48:46,040 --> 00:48:49,360 which displays files. 670 00:48:49,360 --> 00:48:55,910 So if I do that, printenv can take 1 argument or 0 arguments, 671 00:48:55,910 --> 00:48:58,070 not more than 1. 672 00:49:01,800 --> 00:49:05,690 There are other commands also, but we're not going to get into all that today. 673 00:49:05,690 --> 00:49:11,010 Remember there were the modifiers for the shell variables like :h, 674 00:49:11,010 --> 00:49:14,350 which will drop the last element of a pathname, 675 00:49:14,350 --> 00:49:17,950 or :r, which will drop an extension. 676 00:49:17,950 --> 00:49:23,110 Those now apply to the environment variables too. They didn't used to. 677 00:49:23,110 --> 00:49:24,960 It used to be they couldn't be modified. Now they can be. 678 00:49:24,960 --> 00:49:29,190 It's one of the advances with the developments of the shells over the years. 679 00:49:29,190 --> 00:49:35,620 I was saying that the shells as part of the environments 680 00:49:35,620 --> 00:49:43,040 and shell variables in the C-shell are, with some exceptions, distinct sets. 681 00:49:43,040 --> 00:49:46,790 You can establish an environment variable and a shell variable with the same name. 682 00:49:46,790 --> 00:49:49,220 They will be different variables; they can have different values. 683 00:49:49,220 --> 00:49:53,090 Changing the value of one won't change the value of the other. 684 00:49:53,090 --> 00:49:58,070 These variables are all evaluated with the dollar sign--$a, $whatever. 685 00:49:58,070 --> 00:50:02,340 So what if you have this? Do you know which one you get? 686 00:50:02,340 --> 00:50:04,520 In my tests I got the shell variable, 687 00:50:04,520 --> 00:50:07,240 but this isn't documented and you can't rely on that. 688 00:50:07,240 --> 00:50:10,270 So I ask you, is creating shell and environment variables 689 00:50:10,270 --> 00:50:13,490 with the same names a good idea? No. Okay. 690 00:50:13,490 --> 00:50:17,460 What are those major exceptions in which the environment and shell variables 691 00:50:17,460 --> 00:50:19,860 are linked to each other? 692 00:50:19,860 --> 00:50:27,470 There are these 4. 693 00:50:32,030 --> 00:50:35,510 Capital letter TERM environment variable, 694 00:50:35,510 --> 00:50:41,540 shell variable term in small letters, type of terminal emulation. 695 00:50:41,540 --> 00:50:47,430 I'm just going to go over here and I'm going to do echo, a useful command here, 696 00:50:47,430 --> 00:50:52,560 $TERM $term. And there. 697 00:50:52,560 --> 00:51:00,570 xterm is a terminal type for windows displayed in the x Window System. 698 00:51:00,570 --> 00:51:04,330 xterm-color is a variation of that that allows different colors. 699 00:51:04,330 --> 00:51:06,580 Why do we define these? What is this good for? 700 00:51:06,580 --> 00:51:09,740 Commands that rearrange the screen like the editor 701 00:51:09,740 --> 00:51:13,680 send particular sequences, called escape sequences, 702 00:51:13,680 --> 00:51:18,160 to a terminal or a window to rearrange it and so forth. 703 00:51:18,160 --> 00:51:20,990 Those sequences are different for different types of terminals. 704 00:51:20,990 --> 00:51:23,100 This tells it which ones to use. 705 00:51:23,100 --> 00:51:25,900 Sometimes there are issues there. 706 00:51:25,900 --> 00:51:28,600 You might want to change that. 707 00:51:28,600 --> 00:51:30,780 If things aren't working, sometimes the terminal type is set wrong, 708 00:51:30,780 --> 00:51:36,440 you may be able to fix it by redefining the term variable. 709 00:51:36,440 --> 00:51:43,420 In these cases, changing one variable, the environment variable or the shell variable, 710 00:51:43,420 --> 00:51:45,970 should change the other one. 711 00:51:45,970 --> 00:51:50,970 I've discovered through experience that changing TERM in capital letters 712 00:51:50,970 --> 00:51:54,060 doesn't always change shell variable term in small letters. 713 00:51:54,060 --> 00:51:55,550 This is a bug. 714 00:51:55,550 --> 00:51:59,400 I don't know if that's always true. Most of the time it isn't true, but it can be. 715 00:51:59,400 --> 00:52:02,490 So if you make a change, just check that out. 716 00:52:02,490 --> 00:52:05,830 It's not often that you need to change that value, but once in a while you do. 717 00:52:05,830 --> 00:52:08,260 Environment variable USER. 718 00:52:08,260 --> 00:52:12,070 Again, environment variable in capital letters, shell variable in small letters. 719 00:52:12,070 --> 00:52:13,710 This is your username. 720 00:52:13,710 --> 00:52:16,730 It's only under very exceptional circumstances 721 00:52:16,730 --> 00:52:18,420 that you would want to change that. 722 00:52:18,420 --> 00:52:22,350 If your username is someone else, it can throw all sorts of things off. 723 00:52:22,350 --> 00:52:26,040 Home directory, user's home directory. 724 00:52:26,040 --> 00:52:28,060 Again, you wouldn't want to change that. 725 00:52:28,060 --> 00:52:32,260 Notice in all of these cases and the one that we're about to cover, the path variable, 726 00:52:32,260 --> 00:52:37,070 environment variable is in capital letters and the bound shell variable is in small letters. 727 00:52:37,070 --> 00:52:39,240 If you change one, you should change the other. 728 00:52:39,240 --> 00:52:45,960 This kind of binding cannot be established as you can't bind 2 variables, 729 00:52:45,960 --> 00:52:50,570 other than these 4, and the binding in these variables can't be undone, 730 00:52:50,570 --> 00:52:52,090 you can't separate them. 731 00:52:52,090 --> 00:52:55,820 So these 4 pairs of variables are bound. 732 00:52:55,820 --> 00:52:59,020 They always will be. None others will be. 733 00:52:59,020 --> 00:53:05,720 In addition, it would be possible to create variables with the same names 734 00:53:05,720 --> 00:53:07,780 of the opposite types. 735 00:53:07,780 --> 00:53:11,600 You could make a shell variable term in small letters 736 00:53:11,600 --> 00:53:14,990 or an environment variable TERM in capital letters. 737 00:53:14,990 --> 00:53:19,040 Those variables would be independent of these paired variables 738 00:53:19,040 --> 00:53:20,780 and they would be independent of each other. 739 00:53:20,780 --> 00:53:23,780 I can't imagine why you would do that unless you want to confuse people. 740 00:53:24,600 --> 00:53:29,730 This one here, path variable, this is a really important one. 741 00:53:29,730 --> 00:53:35,550 Another thing here is that there can be cases 742 00:53:35,550 --> 00:53:40,430 of variables with similar paired names which aren't bound to each other. 743 00:53:40,430 --> 00:53:45,000 There can be variables, SHELL and shell, in capital and small letters. 744 00:53:45,000 --> 00:53:48,300 Based on that name, you don't know if that variable is a shell variable 745 00:53:48,300 --> 00:53:51,580 or an environment variable, and they're not bound to each other. 746 00:53:51,580 --> 00:53:55,300 So that kind of paired names doesn't imply bound variables. 747 00:53:55,300 --> 00:53:58,830 The path variable, which I was showing before, 748 00:53:58,830 --> 00:54:01,880 is a list of pathnames in which the shell looks for commands. 749 00:54:01,880 --> 00:54:12,320 Let's get over to this window here and we'll do echo $PATH, capital letters-- 750 00:54:12,320 --> 00:54:20,230 environment variable--echo $path, small letters--shell variable. 751 00:54:20,230 --> 00:54:24,980 Notice that the list of directories is the same. These are bound. 752 00:54:24,980 --> 00:54:26,590 Change one, you change the other. 753 00:54:26,590 --> 00:54:32,970 In the environment variable the elements are separated by colons. Notice that. 754 00:54:32,970 --> 00:54:35,130 The shell variables are separated by spaces. 755 00:54:35,130 --> 00:54:38,760 This environment variable is a single string. 756 00:54:38,760 --> 00:54:41,480 The shell variable is an array. 757 00:54:41,480 --> 00:54:43,490 The Bourne shell didn't have arrays. 758 00:54:43,490 --> 00:54:46,600 Bash does, but this is already a fixed part of the shell. 759 00:54:46,600 --> 00:54:48,660 This is a single string and not an array. 760 00:54:48,660 --> 00:54:50,420 The C-shell always had arrays. 761 00:54:50,420 --> 00:54:52,630 The arrays are much easier to work with. 762 00:54:52,630 --> 00:54:54,400 You can refer to parts of it. 763 00:54:54,400 --> 00:55:02,350 So echo $path[1] and I get /usr/bin, the first element. 764 00:55:02,350 --> 00:55:09,950 Again, remember dollar sign stands for the last element of the history list. 765 00:55:09,950 --> 00:55:16,850 What happens there? It tried to find dollar sign as a variable symbol. 766 00:55:16,850 --> 00:55:20,850 I escape it. Oops. It wouldn't take that either. 767 00:55:20,850 --> 00:55:23,690 Some of these things don't work so well. 768 00:55:23,690 --> 00:55:28,140 Maybe we'll just leave that out. 769 00:55:28,140 --> 00:55:36,980 Asterisk refers to the whole thing, but that's what you get if you don't specify an element. 770 00:55:36,980 --> 00:55:46,170 Another way that array variables can be manipulated, 771 00:55:46,170 --> 00:55:49,500 number of elements there, 7 elements. 772 00:55:49,500 --> 00:55:53,410 Here we put the pound sign before the variable name. 773 00:55:53,410 --> 00:55:58,280 Here's another one. Put a question mark there. 774 00:55:58,280 --> 00:56:03,170 That is a logical value. That indicates that the variable exists. 775 00:56:03,170 --> 00:56:05,160 It's another way of working with variables. 776 00:56:05,160 --> 00:56:06,660 That, by the way, doesn't have to be an array variable. 777 00:56:06,660 --> 00:56:08,210 That could be any variable. 778 00:56:08,210 --> 00:56:11,840 And if I do, there's no such variable and I get a 0. 779 00:56:11,840 --> 00:56:14,990 Another little thing there about variable evaluations. 780 00:56:23,670 --> 00:56:32,950 Back to this one here, if for some reason you wanted to work with this 781 00:56:32,950 --> 00:56:37,990 rather than working with the array, the shell variable, 782 00:56:37,990 --> 00:56:41,470 there are commands that can separate these things based on the colon. 783 00:56:41,470 --> 00:56:44,080 In fact, if you're going to be doing this in the Bash shell possibly, 784 00:56:44,080 --> 00:56:47,110 some kind of a script, that would be probably how you would do it. 785 00:56:47,110 --> 00:56:50,350 But in the C-shell it's much easier to use the array. 786 00:56:50,350 --> 00:56:58,250 In the Bourne shell, variables are assigned by a single expression like this, 787 00:56:58,250 --> 00:57:01,760 like the way you might assign a variable in a programming language, 788 00:57:01,760 --> 00:57:05,110 and here there must be no spaces. 789 00:57:05,110 --> 00:57:09,110 It's necessary that it be just 1 string. 790 00:57:09,110 --> 00:57:14,980 In the Bourne-type shells, all variables are shell variables. 791 00:57:14,980 --> 00:57:19,250 Environment variables are a subset of the shell variables. 792 00:57:19,250 --> 00:57:24,060 They are distinguished from the non-environment variables by exporting. 793 00:57:24,060 --> 00:57:28,860 The command to do that is export, like export PRINTER. 794 00:57:28,860 --> 00:57:34,930 If we were to define such a variable, 795 00:57:34,930 --> 00:57:38,480 if we wanted a printing command to find it, it would have to be an environment variable, 796 00:57:38,480 --> 00:57:40,730 and that's how we make it one. 797 00:57:40,730 --> 00:57:42,090 Here there's something kind of confusing. 798 00:57:42,090 --> 00:57:50,430 This expression, export to the environment, derives from this Bourne shell concept, 799 00:57:50,430 --> 00:57:54,520 and yet that expression is used in descriptions of the C-shell, 800 00:57:54,520 --> 00:57:57,920 where there is no such command as export. 801 00:57:57,920 --> 00:58:06,200 If you just say export by itself, you get a list of exported-- 802 00:58:06,200 --> 00:58:10,620 So if I just do export here, no such thing. 803 00:58:13,620 --> 00:58:15,200 Okay, there we go. 804 00:58:15,200 --> 00:58:17,010 These things, by the way, are also defined by the shell. 805 00:58:17,010 --> 00:58:19,400 I didn't define any of these by myself. 806 00:58:19,400 --> 00:58:23,550 The shell does all sorts of things by itself. 807 00:58:23,550 --> 00:58:26,650 It should do things automatically. 808 00:58:30,240 --> 00:58:36,880 In Bash or Korn shell, you can run a command like this, 809 00:58:36,880 --> 00:58:42,000 which will both give a variable a value and export it in 1 command. 810 00:58:42,000 --> 00:58:46,150 In the Bourne shell they have to be separate commands like export a. 811 00:58:46,150 --> 00:58:48,410 Here is another aspect that's confusing. 812 00:58:48,410 --> 00:58:52,220 The set command in the C-shell defines variables 813 00:58:52,220 --> 00:58:55,550 and with no arguments tells you what the variables' values are. 814 00:58:55,550 --> 00:59:01,140 In the Bash shell, the set command with no arguments does the same thing, 815 00:59:01,140 --> 00:59:03,580 but with arguments it does something quite different. 816 00:59:03,580 --> 00:59:06,200 So these are the various arguments here. 817 00:59:06,200 --> 00:59:10,460 Some of these are environment variables, some of them are shell variables. 818 00:59:10,460 --> 00:59:13,200 All of them are shell variables really. Some of those are environment variables. 819 00:59:15,690 --> 00:59:23,920 The set command with arguments can be used to operate 820 00:59:23,920 --> 00:59:28,220 on the positional parameters to a script, 821 00:59:28,220 --> 00:59:33,910 which is a way of getting them all at once. 822 00:59:33,910 --> 00:59:36,150 We can't really go into that today. 823 00:59:36,150 --> 00:59:39,580 It can also be used to change shell behavior. 824 00:59:39,580 --> 00:59:46,700 Particularly in Bash there are variables which will determine how the shell behaves. 825 00:59:46,700 --> 00:59:51,310 Then also just this one command that you might see, this command. 826 00:59:51,310 --> 00:59:59,050 Typeset followed by variables and variable types is used in the Korn and Bash shells. 827 00:59:59,050 --> 01:00:04,970 It's not mandatory but it can be used to restrict the values of variables, 828 01:00:04,970 --> 01:00:08,400 which can be useful to prevent errors, and it's fairly common. 829 01:00:08,400 --> 01:00:11,640 So I'm just mentioning that in case you see it somewhere. 830 01:00:17,290 --> 01:00:19,160 The where command. 831 01:00:19,160 --> 01:00:22,490 Remember I mentioned earlier the where command in the C-shell, 832 01:00:22,490 --> 01:00:28,750 which can tell you the location of a command pathname. 833 01:00:28,750 --> 01:00:32,580 Here is command substitution. 834 01:00:32,580 --> 01:00:41,900 You should find on your keyboard somewhere a character that looks like this. 835 01:00:41,900 --> 01:00:44,910 The location on the keyboard is going to vary. 836 01:00:44,910 --> 01:00:47,050 We've called it backquote. It's about the size of a quote. 837 01:00:47,050 --> 01:00:48,720 It goes from upper left to lower right. 838 01:00:48,720 --> 01:00:52,690 Here on my Mac keyboard it's in the upper left-hand corner. 839 01:00:52,690 --> 01:00:58,150 That character can be used to execute a command within a command. 840 01:00:58,150 --> 01:01:03,400 If you have an expression inside backquotes, 841 01:01:03,400 --> 01:01:07,080 that expression is a command, it's run. 842 01:01:07,080 --> 01:01:09,010 The output of that command 843 01:01:09,010 --> 01:01:11,980 is then substituted for the whole backquote expression 844 01:01:11,980 --> 01:01:16,110 inside a longer command which then runs with that output 845 01:01:16,110 --> 01:01:22,010 as part of its string of arguments and so forth. 846 01:01:22,010 --> 01:01:28,640 Here is a command which uses that. 847 01:01:28,640 --> 01:01:32,340 Let's demonstrate the operation here. 848 01:01:44,980 --> 01:01:49,090 Let's go up here, take out the backquotes. 849 01:01:49,090 --> 01:01:54,410 Control A gets me to the beginning of the line with the Emacs editing syntax. 850 01:01:54,410 --> 01:02:00,380 So far the pathnames is what where does, 851 01:02:00,380 --> 01:02:05,040 but when I do it like this, it then plugs in that list of pathnames 852 01:02:05,040 --> 01:02:08,750 in place of this whole backquote expression and runs ls -l on them. 853 01:02:08,750 --> 01:02:11,120 Kind of convenient, huh? 854 01:02:11,120 --> 01:02:14,860 So that's one neat thing. That's how backquotes work. 855 01:02:14,860 --> 01:02:17,560 Now let's go down a little further. 856 01:02:17,560 --> 01:02:22,050 These are aliases. I actually use these. 857 01:02:22,050 --> 01:02:26,410 I'll try to get this in with 1 editing operation. 858 01:02:34,900 --> 01:02:36,900 Okay. 859 01:02:36,900 --> 01:02:39,630 Now let's see how those definitions came out. 860 01:02:39,630 --> 01:02:44,930 alias lwh telling me how it's defined. 861 01:02:44,930 --> 01:02:51,210 Notice it's just this, but the outer quotes have been taken off 862 01:02:51,210 --> 01:02:53,750 and the exclamation point is taken off. 863 01:02:53,750 --> 01:02:58,940 !*, complete list of all the arguments. 864 01:02:58,940 --> 01:03:03,580 In an alias definition it will apply back to where I use this. 865 01:03:03,580 --> 01:03:10,620 lwh ksh bash. Okay. 866 01:03:10,620 --> 01:03:13,960 See how that works? It saves me some typing. 867 01:03:13,960 --> 01:03:16,440 Let's go up a little bit just to mention something else here. 868 01:03:19,150 --> 01:03:23,120 Notice here these different shells. I should have mentioned this before. 869 01:03:23,120 --> 01:03:36,060 The csh has a 2 over here and so does /bin/tcsh. 870 01:03:36,060 --> 01:03:39,870 We could establish by other means that those are actually the same file. 871 01:03:39,870 --> 01:03:43,150 Remember I was saying if you type sh you get bash. 872 01:03:43,150 --> 01:03:47,390 Type this and you get this. 873 01:03:47,390 --> 01:03:51,730 But those aren't linked. Those have single ones there. 874 01:03:51,730 --> 01:03:54,910 And this isn't the kind of file which can call another one. 875 01:03:54,910 --> 01:03:59,460 So those are separate files; the C-shell ones are the same file. 876 01:03:59,460 --> 01:04:03,640 Back down here, the other one here, this alias, 877 01:04:03,640 --> 01:04:09,090 note that's running this command, file. 878 01:04:09,090 --> 01:04:13,810 That alias runs that. File tells you the type of a file. 879 01:04:13,810 --> 01:04:20,330 So fwh ksh bash. Okay. 880 01:04:20,330 --> 01:04:23,230 That's the output of the file command. 881 01:04:23,230 --> 01:04:24,630 I don't know if you know what this means here, 882 01:04:24,630 --> 01:04:26,750 Mach-O universal binary with 2 architectures. 883 01:04:26,750 --> 01:04:30,470 There are 2 possible processor types in Mac, 884 01:04:30,470 --> 01:04:34,780 and some programs were written to be able to run with both, 885 01:04:34,780 --> 01:04:37,950 and the file command can determine that, so that's what this means. 886 01:04:37,950 --> 01:04:40,660 Both of these files were written that way. 887 01:04:40,660 --> 01:04:43,760 So we see how the alias works, we see how the backquote works, 888 01:04:43,760 --> 01:04:48,640 we see how the actual file ls or file works. 889 01:04:52,050 --> 01:04:57,000 This might not work. Try "where where" and "lwh where". Okay, let's try that. 890 01:04:57,000 --> 01:05:01,040 where where. 891 01:05:01,040 --> 01:05:03,500 where is a shell built-in. 892 01:05:03,500 --> 01:05:06,970 Remember earlier we showed that Bash didn't have where. 893 01:05:06,970 --> 01:05:10,080 If you type where in the Bash shell, you get an error message. 894 01:05:10,080 --> 01:05:12,540 It's just part of the shell rather than being a separate command. 895 01:05:12,540 --> 01:05:20,000 What happens if I type lwh looking for where? See what happens there. 896 01:05:20,000 --> 01:05:22,850 Ran where where, got this output, and then tried to run ls 897 01:05:22,850 --> 01:05:25,600 as l on where is a shell built-in. 898 01:05:25,600 --> 01:05:28,790 where is there, but the other ones don't exist. 899 01:05:28,790 --> 01:05:32,090 None of these exist, actually. 900 01:05:32,090 --> 01:05:35,560 So that doesn't always work, and it also illustrates how some things 901 01:05:35,560 --> 01:05:39,580 don't do quite what you might have thought. 902 01:05:40,930 --> 01:05:43,010 Let's go down a little further here. 903 01:05:44,890 --> 01:05:54,760 This here is in Bash. That is also command substitution like the backquote. 904 01:05:54,760 --> 01:06:05,280 But unlike backquote, it uses this variable style. 905 01:06:05,280 --> 01:06:09,860 There are a number of expressions which begin with a dollar sign, 906 01:06:09,860 --> 01:06:16,070 and while these aren't variables, they borrowed the use of the dollar sign 907 01:06:16,070 --> 01:06:19,570 to indicate an expression of some kind. 908 01:06:19,570 --> 01:06:23,550 That can be surrounded by parentheses or brackets or double parentheses, 909 01:06:23,550 --> 01:06:26,320 which has a different purpose. 910 01:06:26,320 --> 01:06:29,500 Single parentheses here are a command substitution just like the backquotes. 911 01:06:29,500 --> 01:06:32,720 Double parentheses is actually an arithmetic operation. 912 01:06:32,720 --> 01:06:35,380 There are other syntaxes, other operations. 913 01:06:35,380 --> 01:06:41,520 Backquote syntax is available in Bash. 914 01:06:41,520 --> 01:06:46,780 However, this one is preferable. It's much easier to read and it allows nesting. 915 01:06:46,780 --> 01:06:51,300 You can have inside $(command) another command, 916 01:06:51,300 --> 01:06:54,590 something like-- 917 01:07:14,560 --> 01:07:18,210 I get a list there. 918 01:07:18,210 --> 01:07:21,670 That would work if I had the backquote also. 919 01:07:32,050 --> 01:07:38,470 What if I want to do something like-- 920 01:08:03,390 --> 01:08:06,430 You probably wouldn't actually use this command, 921 01:08:06,430 --> 01:08:14,160 but this internal command substitution echoes the names of all files beginning with a, 922 01:08:14,160 --> 01:08:18,229 then this one runs ls -l on those files, 923 01:08:18,229 --> 01:08:20,500 and then this one just echoes the output. 924 01:08:21,729 --> 01:08:24,479 You probably wouldn't do this; you'd just do the echo or ls, 925 01:08:24,479 --> 01:08:29,450 but this illustrates how the nesting of commands works. 926 01:08:29,450 --> 01:08:34,380 So just another feature here. 927 01:08:34,380 --> 01:08:37,450 I mentioned this earlier, that when you have where in the C-shell, 928 01:08:37,450 --> 01:08:42,770 type works in the Bourne-type shells for locating commands. 929 01:08:48,939 --> 01:08:52,270 Built-in commands, just what I was saying there. 930 01:08:52,270 --> 01:08:54,640 Commands are part of the shell, like where. 931 01:08:54,640 --> 01:08:59,880 When the shell executes a command like ls, it locates it through the path, 932 01:08:59,880 --> 01:09:03,029 finds it in some directory somewhere, 933 01:09:03,029 --> 01:09:05,800 reads that into memory, creates a new shell, 934 01:09:05,800 --> 01:09:08,960 reads the command ls or whatever into the shell 935 01:09:08,960 --> 01:09:11,450 where the environment variables are already located, 936 01:09:11,450 --> 01:09:14,000 and then it transfers execution to it. 937 01:09:14,000 --> 01:09:18,319 Built-in command, the code for that command is inside the shell, 938 01:09:18,319 --> 01:09:21,460 so the shell just starts executing part of its own code. 939 01:09:21,460 --> 01:09:24,569 where is such a command. It actually gets faster. 940 01:09:24,569 --> 01:09:28,380 It doesn't have to read anything in memory; it's already in memory. 941 01:09:28,380 --> 01:09:32,460 Built-in commands always take precedence over commands with the same name. 942 01:09:32,460 --> 01:09:36,050 Commands that are in directories in the path may have the same name, 943 01:09:36,050 --> 01:09:39,090 commands in different directories, files in different directories. 944 01:09:39,090 --> 01:09:41,740 The one that occurs earlier in the path is the one you'll get. 945 01:09:41,740 --> 01:09:43,770 If there is a built-in command, you always get it. 946 01:09:43,770 --> 01:09:47,890 There's no way to give it a lower precedence than a command in the path. 947 01:09:47,890 --> 01:09:54,140 If you want to get that path command, you can type the full pathname. 948 01:09:54,140 --> 01:09:55,850 If there were a command where in the path somewhere, 949 01:09:55,850 --> 01:09:58,440 you could type /bin/where and you'd get it. 950 01:09:58,440 --> 01:10:01,800 If you don't want to type the whole pathname, you could define an alias. 951 01:10:01,800 --> 01:10:06,310 In fact, if you gave the alias the same name as the built-in command, it would work 952 01:10:06,310 --> 01:10:08,790 because the alias definition is evaluated 953 01:10:08,790 --> 01:10:13,220 before the shell determines that it's a built-in command which should be executed. 954 01:10:18,810 --> 01:10:23,440 Then this gets a little more complicated with some commands here. 955 01:10:23,440 --> 01:10:29,880 The case of some commands are actually built-in commands and in the path. 956 01:10:29,880 --> 01:10:34,140 One of them is echo, the command I just used a little while ago in those examples. 957 01:10:34,140 --> 01:10:37,410 Echo is a command in the path and it's in every shell. 958 01:10:37,410 --> 01:10:40,580 They don't necessarily all behave the same way. 959 01:10:40,580 --> 01:10:42,970 It was originally a command only in the path. 960 01:10:42,970 --> 01:10:45,280 It was built in to the shells later. 961 01:10:45,280 --> 01:10:48,080 Because there are options which depend on the environment 962 01:10:48,080 --> 01:10:52,970 and the command line options, the built-in commands 963 01:10:52,970 --> 01:10:57,030 were written to function the same as the command that had been in the path, 964 01:10:57,030 --> 01:10:59,670 it's unlikely they would have been written that way 965 01:10:59,670 --> 01:11:01,720 if the command hadn't already been written for the path. 966 01:11:01,720 --> 01:11:06,180 So this has side effects. Its history has effects here. 967 01:11:06,180 --> 01:11:08,380 There are options there. 968 01:11:14,280 --> 01:11:23,060 There's also an option defined by a variable in the tcsh called echo_style. 969 01:11:23,060 --> 01:11:27,700 That's one of these variables that can change the way that echo works. 970 01:11:27,700 --> 01:11:30,910 There are other cases in which you can assign a variable 971 01:11:30,910 --> 01:11:36,290 that changes the way that the shell operation, including a built-in command, works. 972 01:11:36,290 --> 01:11:38,130 It wouldn't affect anything else 973 01:11:38,130 --> 01:11:40,640 since other commands don't have access to the shell variables, 974 01:11:40,640 --> 01:11:42,090 only the environment variables. 975 01:11:42,090 --> 01:11:45,360 But shell operations can read the shell variables. 976 01:11:45,360 --> 01:11:50,710 That won't work for csh. That's only tcsh. That's one of the enhancements. 977 01:11:58,540 --> 01:12:04,620 Parsing has sequences when it evaluates metacharacters, 978 01:12:04,620 --> 01:12:08,140 when it evaluates variables, aliases, history references. 979 01:12:08,140 --> 01:12:11,830 There's a particular sequence for these things. 980 01:12:11,830 --> 01:12:13,730 If it does things in a particular sequence 981 01:12:13,730 --> 01:12:16,080 and gets to something that's an expression of a sort 982 01:12:16,080 --> 01:12:20,650 which has already been evaluated, it won't evaluate it again. 983 01:12:20,650 --> 01:12:24,520 If it gets it, then it will just pass on the characters. 984 01:12:24,520 --> 01:12:29,920 So if evaluation of some expressions like command substitution 985 01:12:29,920 --> 01:12:36,850 or variable or whatever gives rise to an expression 986 01:12:36,850 --> 01:12:39,240 which you would want to be evaluated, 987 01:12:39,240 --> 01:12:42,510 that will work only if that evaluation occurs later in the sequence. 988 01:12:42,510 --> 01:12:45,010 I hope I'm being clear there. 989 01:12:45,010 --> 01:12:50,460 That parsing sequence, an operation in the C-shell, 990 01:12:50,460 --> 01:12:56,490 isn't the same for built-in commands as it is for non-built-in commands. 991 01:12:56,490 --> 01:12:58,890 I'm not sure about Bash there. 992 01:12:58,890 --> 01:13:02,450 For example, if a shell variable produced a history reference, 993 01:13:02,450 --> 01:13:04,230 it probably would not go back in the history. 994 01:13:04,230 --> 01:13:06,010 It would just get the exclamation point. 995 01:13:06,010 --> 01:13:08,840 In fact, we can just try that out right now. 996 01:13:09,720 --> 01:13:18,240 set a= and we'll have to put this in there. 997 01:13:30,690 --> 01:13:34,580 Oh, wait. Sorry. I did this in the Bash. I wanted to do it here. 998 01:13:53,470 --> 01:13:56,080 See, so it didn't evaluate that history reference 999 01:13:56,080 --> 01:14:00,520 because it was already past the point of evaluating history expressions 1000 01:14:00,520 --> 01:14:02,720 when it evaluated the variable. 1001 01:14:02,720 --> 01:14:05,550 So that's 1 effect of parsing. 1002 01:14:05,550 --> 01:14:08,760 And again, built-in commands aren't done the same way. 1003 01:14:08,760 --> 01:14:11,230 All right. Let's go to the next one here. 1004 01:14:11,230 --> 01:14:16,060 This is intended to be 1 line, but it's making it easier to read. 1005 01:14:19,130 --> 01:14:21,530 What does that do? 1006 01:14:21,530 --> 01:14:28,640 You may recall that we can evaluate asterisks as filename wildcards, 1007 01:14:28,640 --> 01:14:33,890 and there are other filename wildcards like the question mark and bracket expressions. 1008 01:14:33,890 --> 01:14:39,000 That kind of evaluation is called globbing. 1009 01:14:39,000 --> 01:14:46,290 set noglob at the beginning of this command says don't do that. 1010 01:14:46,290 --> 01:14:53,370 unset noglob says go back to doing that. 1011 01:14:53,370 --> 01:14:56,440 Note that set glob would not have that effect. 1012 01:14:56,440 --> 01:15:00,800 In ordinary language, set glob or unset noglob would seem to be equivalent, 1013 01:15:00,800 --> 01:15:03,290 but here it isn't. It's unset noglob. 1014 01:15:05,120 --> 01:15:07,910 Now tset. tset stood for terminal set. 1015 01:15:07,910 --> 01:15:11,840 It's not used that often now, but before windowing systems became available 1016 01:15:11,840 --> 01:15:15,760 and you had a single terminal, you might have to determine the type. 1017 01:15:15,760 --> 01:15:18,700 And if something was coming over an Ethernet or from the network, 1018 01:15:18,700 --> 01:15:21,120 you might want to say it's a vt100. 1019 01:15:21,120 --> 01:15:26,630 VT100 is kind of a standard in the terminal business. It comes from the DEC terminal. 1020 01:15:26,630 --> 01:15:35,270 If you just do dialup--notice that? This goes back a ways, huh? 1021 01:15:35,270 --> 01:15:39,520 So if we just do tset over here, 1022 01:15:39,520 --> 01:15:45,250 if I just do tset, it's resetting my terminal, but you didn't see anything. 1023 01:15:45,250 --> 01:15:47,340 It didn't really change anything. 1024 01:15:47,340 --> 01:15:48,620 -s 1025 01:15:49,900 --> 01:15:51,480 Okay. 1026 01:15:51,480 --> 01:15:53,350 setenv TERM xterm-color. 1027 01:15:53,350 --> 01:15:57,080 We already know that the term was set that way, so that didn't change. 1028 01:15:57,080 --> 01:15:58,860 That's the way we'd want to do it. 1029 01:15:58,860 --> 01:16:07,080 But notice that this command, tset -s, just output these commands. It didn't run them. 1030 01:16:07,080 --> 01:16:09,770 It didn't run these commands; it output them. 1031 01:16:09,770 --> 01:16:13,650 So this is intended to produce commands which will then be run. 1032 01:16:13,650 --> 01:16:16,360 You remember the command in that file I just showed you had a Q in it. 1033 01:16:16,360 --> 01:16:18,910 So let's do that. 1034 01:16:18,910 --> 01:16:23,750 The Q suppresses some output, but that doesn't matter here, as you can see. 1035 01:16:23,750 --> 01:16:27,980 I'm just doing that to show you that it didn't matter. 1036 01:16:27,980 --> 01:16:31,870 This is in backquote syntax. 1037 01:16:31,870 --> 01:16:35,340 Note the backquote here, backquote here. 1038 01:16:35,340 --> 01:16:37,680 I'm omitting these things here. 1039 01:16:37,680 --> 01:16:39,570 These are cases of telling it what to do 1040 01:16:39,570 --> 01:16:42,050 in the case of particular types of terminals-- 1041 01:16:42,050 --> 01:16:45,400 Ethernet, network, dialup, what have you. 1042 01:16:45,400 --> 01:16:48,050 It doesn't matter here because we're not actually doing any of these things. 1043 01:16:48,050 --> 01:16:49,720 I'm just illustrating the command. 1044 01:16:49,720 --> 01:16:55,170 If I do this with the backquote, what am I going to get? 1045 01:16:55,170 --> 01:17:00,210 Also notice here that this included the set noglob and the unset noglob, 1046 01:17:00,210 --> 01:17:02,630 so those are now redundant in the definition. 1047 01:17:02,630 --> 01:17:05,380 That wasn't always true, but now they're included in this command. 1048 01:17:05,380 --> 01:17:08,890 But let's see what happens if I do that 1049 01:17:08,890 --> 01:17:12,570 and go to the beginning of the line with Control A and I do that. 1050 01:17:14,380 --> 01:17:18,040 Okay, set: Command not found. That's kind of odd, isn't it? 1051 01:17:18,040 --> 01:17:20,570 set is a well-known command. It's part of the shell. 1052 01:17:20,570 --> 01:17:24,040 set: Command not found? Why is that? 1053 01:17:24,040 --> 01:17:26,790 Hmm. Well, let's think about this. 1054 01:17:26,790 --> 01:17:31,100 It's running a backquote command substitution, 1055 01:17:31,100 --> 01:17:37,430 and that occurs at a certain part of the sequence of parsing the command. 1056 01:17:37,430 --> 01:17:40,360 set is a built-in command. 1057 01:17:40,360 --> 01:17:43,900 So by the time it does that command substitution, 1058 01:17:43,900 --> 01:17:48,280 it's already gotten past the point of identifying built-in commands. 1059 01:17:48,280 --> 01:17:51,900 So it treats set as if it were a command in the path. 1060 01:17:51,900 --> 01:17:55,440 Needless to say, it doesn't find it and you get an error. 1061 01:17:55,440 --> 01:17:59,300 Well. There's an example of parsing sequence. 1062 01:17:59,300 --> 01:18:01,460 And what do we do about that? 1063 01:18:01,460 --> 01:18:04,800 Notice this very interesting command here, eval. 1064 01:18:04,800 --> 01:18:06,530 I wonder what that does. 1065 01:18:06,530 --> 01:18:08,760 If you look at the manual--and let's just do that 1066 01:18:08,760 --> 01:18:12,000 to show how confusing these manuals are-- 1067 01:18:12,000 --> 01:18:19,400 man tcsh, confused manual, finding things here is not easy either. 1068 01:18:19,400 --> 01:18:31,850 Here we go, eval arg, so we can have 1 or more arguments 1069 01:18:31,850 --> 01:18:34,090 and there's a list of things there. 1070 01:18:34,090 --> 01:18:37,730 Treats the arguments as inputs to the shell 1071 01:18:37,730 --> 01:18:43,600 and executes the resulting commands in the context of the current shell. 1072 01:18:43,600 --> 01:18:46,900 This is usually used to execute commands generated as the result of command 1073 01:18:46,900 --> 01:18:51,310 or variable substitution because parsing occurs before these substitutions. 1074 01:18:51,310 --> 01:18:52,580 Very good. 1075 01:18:52,580 --> 01:18:54,740 And here they even refer to the tset command for a sample use 1076 01:18:54,740 --> 01:18:57,700 like the one I just showed you. 1077 01:18:57,700 --> 01:19:00,440 Now I have to get the window back to a useful place. 1078 01:19:03,150 --> 01:19:07,800 Let's get over here and we'll see that eval is used just before that. 1079 01:19:07,800 --> 01:19:14,010 So let's see what happens if we put--here we go up with the arrows to that command 1080 01:19:14,010 --> 01:19:20,940 and Control A to the beginning, eval. 1081 01:19:20,940 --> 01:19:22,850 Okay, so it works. 1082 01:19:22,850 --> 01:19:26,440 When you do eval, it takes what comes after it and makes it a command. 1083 01:19:26,440 --> 01:19:29,460 This enables you to essentially parse it twice. 1084 01:19:29,460 --> 01:19:33,710 The section here runs this command inside the backquotes, 1085 01:19:33,710 --> 01:19:36,210 gets the output. 1086 01:19:36,210 --> 01:19:42,850 Output is supposed to be run as those commands here like these 1087 01:19:42,850 --> 01:19:45,890 at this one and this one. 1088 01:19:45,890 --> 01:19:50,100 So those commands are now here in this sequence, 1089 01:19:50,100 --> 01:19:58,950 but these are built-in commands and it can't get them right away. 1090 01:19:58,950 --> 01:20:06,440 So we go to eval, eval picks that up, starts the whole thing all over again, and it works. 1091 01:20:06,440 --> 01:20:18,460 An example both of backquoting, eval, parsing, consequences of parsing, 1092 01:20:18,460 --> 01:20:21,910 and a command which is probably of very little use to you nowadays. 1093 01:20:21,910 --> 01:20:25,540 Okay. All right, umask. 1094 01:20:25,540 --> 01:20:32,160 Let's look at this command here, umask 022. I wonder what that does. 1095 01:20:32,160 --> 01:20:38,420 Let's just type umask with nothing after it. 22. Okay. 1096 01:20:38,420 --> 01:20:44,350 022 and do it again. 1097 01:20:44,350 --> 01:20:48,580 As you might have guessed, umask with no arguments tells you the current mask; 1098 01:20:48,580 --> 01:20:51,760 umask with arguments makes it that, but that was the one I already had. 1099 01:20:51,760 --> 01:20:53,800 What does 022 mean? 1100 01:21:01,650 --> 01:21:07,080 These are here the protections for a file. 1101 01:21:07,080 --> 01:21:11,440 They determine who is allowed to read or write or execute the file. 1102 01:21:11,440 --> 01:21:16,560 Protections are also called permissions. 1103 01:21:16,560 --> 01:21:21,390 The r stands for read, the w for write, 1104 01:21:21,390 --> 01:21:25,500 and the x, which isn't present there, stands for execute. 1105 01:21:25,500 --> 01:21:27,260 There are 3 categories there. 1106 01:21:27,260 --> 01:21:33,540 The last 3 elements are in the category of user. Those apply to me, the user. 1107 01:21:33,540 --> 01:21:36,870 These 3 here apply to the group. 1108 01:21:36,870 --> 01:21:41,590 The file belongs to 1 group, user may belong to several groups, 1109 01:21:41,590 --> 01:21:47,150 but if the user is in the group to which this file belongs, 1110 01:21:47,150 --> 01:21:51,090 then these protections will apply to him if he's not the user. 1111 01:21:51,090 --> 01:21:54,230 And this one is everyone else. 1112 01:21:55,540 --> 01:21:57,690 These categories are mutually exclusive. 1113 01:21:57,690 --> 01:21:59,750 The user protections apply to him, 1114 01:21:59,750 --> 01:22:03,780 the group protections apply to members of the group other than the user, 1115 01:22:03,780 --> 01:22:08,110 and the other protections only apply to people other than the user and the group members. 1116 01:22:08,110 --> 01:22:12,320 If there's an r or a w or an x, it means that protection is granted. 1117 01:22:12,320 --> 01:22:13,950 If there's a hyphen, it means it isn't. 1118 01:22:13,950 --> 01:22:16,690 There actually are other things that can be put in here besides these, 1119 01:22:16,690 --> 01:22:18,350 which I won't get into now. 1120 01:22:18,350 --> 01:22:24,450 The umask defines a default for files that you create. 1121 01:22:24,450 --> 01:22:28,580 And as a mask, basically it says the bits that you don't set. 1122 01:22:28,580 --> 01:22:30,450 How has this become bits? 1123 01:22:30,450 --> 01:22:33,240 If you think of each of these as an octal number, 1124 01:22:33,240 --> 01:22:42,120 this is the 1s bit, this is the 2s, this is the 4s. 1125 01:22:42,120 --> 01:22:45,840 So 0 through 7 1126 01:22:45,840 --> 01:22:51,770 will describe what combination of r's, w's, and x's you have for these 3 1127 01:22:51,770 --> 01:22:53,710 and then a similar number for these and then for these. 1128 01:22:53,710 --> 01:23:12,030 So 022 means 0 for other, 2 for the group, 2 for the user. 1129 01:23:12,030 --> 01:23:15,870 But this is a mask. The mask is what you don't have. 1130 01:23:19,380 --> 01:23:20,610 I'm sorry. I just gave you things in the wrong order. 1131 01:23:20,610 --> 01:23:25,620 It's the first 3. These 3 are the user, these 3 are the group, these 3 are the other. 1132 01:23:25,620 --> 01:23:27,970 Sorry I gave you these in the wrong order. 1133 01:23:27,970 --> 01:23:31,910 The 0, which is the first of those, doesn't display the value, 1134 01:23:31,910 --> 01:23:35,430 but if a number isn't there, it's a 0. 1135 01:23:35,430 --> 01:23:38,370 That means all 3 of these would be allowed. 1136 01:23:38,370 --> 01:23:41,550 Notice that in this particular one the x isn't allowed. 1137 01:23:41,550 --> 01:23:44,090 The reason is that the shell is capable of determining 1138 01:23:44,090 --> 01:23:46,260 whether a file should be executed or not. 1139 01:23:46,260 --> 01:23:49,800 Since this is not an executable file, it didn't set the x. 1140 01:23:49,800 --> 01:23:54,000 The 2 means that write permission, the second category here, 1141 01:23:54,000 --> 01:23:56,500 the one in the middle, is denied. 1142 01:23:56,500 --> 01:23:58,500 So again, these are the things that it denied. 1143 01:23:58,500 --> 01:24:02,080 Well, x is allowed but it's not here because it's not executable 1144 01:24:02,080 --> 01:24:04,260 and similarly for the others. 1145 01:24:04,260 --> 01:24:08,880 So that's a common umask. 1146 01:24:08,880 --> 01:24:14,630 Another common one is 700--give yourself everything and no one else anything. 1147 01:24:14,630 --> 01:24:17,040 And there are other possibilities. 1148 01:24:21,340 --> 01:24:27,110 I'll go back to that. Using the history I can search back for that, lwh to there. 1149 01:24:27,110 --> 01:24:30,210 Okay. So here, these are the shells. 1150 01:24:30,210 --> 01:24:36,020 Bash, the owner who is system account, can do everything. 1151 01:24:36,020 --> 01:24:41,210 Group and everyone else can do read or execute but not write. 1152 01:24:41,210 --> 01:24:44,570 This one doesn't even allow the owner to write to it. 1153 01:24:44,570 --> 01:24:46,460 If the owner wanted to write to it, the system account, 1154 01:24:46,460 --> 01:24:48,020 he would have to change the protection first. 1155 01:24:48,020 --> 01:24:53,940 But again, the umask sets the default by masking it, 1156 01:24:53,940 --> 01:24:57,160 by indicating the bits that will not be set. 1157 01:24:57,160 --> 01:25:04,380 This is typically in one of your initialization files, which is the .cshrc for the C-shell 1158 01:25:04,380 --> 01:25:07,500 or the .profile for the Bourne-type shells. 1159 01:25:07,500 --> 01:25:12,520 It can be elsewhere also if there are other initialization files on the system. 1160 01:25:12,520 --> 01:25:14,610 Anyway, that's umask. 1161 01:25:14,610 --> 01:25:18,180 There's something kind of odd here, 1162 01:25:18,180 --> 01:25:22,800 and that is, why is there a single command for this? 1163 01:25:22,800 --> 01:25:28,690 If I were writing this, I would make it a variable, umask = some value. 1164 01:25:28,690 --> 01:25:31,100 Why is there a whole command just for this purpose? 1165 01:25:31,100 --> 01:25:34,560 The reason is this just goes back to the origins of Unix. 1166 01:25:34,560 --> 01:25:41,050 Unix was just some programming project at Bell Labs in the early 1970s. 1167 01:25:41,050 --> 01:25:42,610 People just got together to program. 1168 01:25:42,610 --> 01:25:45,290 They never intended it to become a worldwide operating system. 1169 01:25:45,290 --> 01:25:47,250 Different people wrote different parts without thinking very much 1170 01:25:47,250 --> 01:25:49,790 of how they were going to be used--rather sketchy. 1171 01:25:49,790 --> 01:25:53,290 And it came together like that, and it's still like that in some respects. 1172 01:25:53,290 --> 01:25:57,930 So that reflects the history, and there are still these inconsistencies and odd elements of it. 1173 01:25:57,930 --> 01:26:00,750 Okay. Next one here. 1174 01:26:08,170 --> 01:26:11,000 As I wrote earlier, the C-shell isn't really used very much for programming, 1175 01:26:11,000 --> 01:26:12,420 although it can be. 1176 01:26:12,420 --> 01:26:15,080 It executes more slowly, again the trade-off between interactive use, 1177 01:26:15,080 --> 01:26:17,820 which has more processing involved than speed, 1178 01:26:17,820 --> 01:26:20,710 which can do without the processing. 1179 01:26:20,710 --> 01:26:28,320 The extra features added to the Bourne shell by the Korn and Bourne-again shells 1180 01:26:28,320 --> 01:26:32,120 don't seem to slow them down, and I don't know why that is. 1181 01:26:32,120 --> 01:26:36,310 It might just be better programming, but I'm not in a position to know. 1182 01:26:36,310 --> 01:26:40,420 Speed here actually isn't such a big deal, although it is mentioned. 1183 01:26:40,420 --> 01:26:43,690 The reason is that shell scripts actually get fairly fast. 1184 01:26:43,690 --> 01:26:46,450 If there is a lot of commands like in a calculational program, 1185 01:26:46,450 --> 01:26:49,110 you probably wouldn't do it in a shell script. 1186 01:26:49,110 --> 01:26:51,450 The operations there are fairly simple and straightforward. 1187 01:26:51,450 --> 01:26:53,960 The ones that I've experienced that are too slow 1188 01:26:53,960 --> 01:26:57,110 involve repeated applications of slow commands. 1189 01:26:57,110 --> 01:27:00,480 Earlier I mentioned the stream editor sed. That command is slow. 1190 01:27:00,480 --> 01:27:03,760 If you execute sed many times, you'll get a slow script, but it's not the shell that's slow. 1191 01:27:03,760 --> 01:27:07,920 Running it in the Bourne shell won't be much faster than running it in the C-shell, 1192 01:27:07,920 --> 01:27:10,070 although there's maybe some advantages there. 1193 01:27:10,070 --> 01:27:12,760 The additional programming capabilities, on the other hand, 1194 01:27:12,760 --> 01:27:17,920 are significant reasons why you would use the Bourne-type shells. 1195 01:27:17,920 --> 01:27:21,390 C-shell has odd features to it-- 1196 01:27:21,390 --> 01:27:25,250 the fact that you don't know if a variable is a shell variable or an environment variable. 1197 01:27:25,250 --> 01:27:27,440 It can be very confusing. 1198 01:27:27,440 --> 01:27:32,170 It's not so easy to write 1199 01:27:32,170 --> 01:27:35,930 just based on your experience of programming in other languages. 1200 01:27:35,930 --> 01:27:41,350 I think you may find the Bourne-type shells more consistent with your experience. 1201 01:27:43,730 --> 01:27:49,270 Some scripts, though, can be thousands of lines in length. 1202 01:27:49,270 --> 01:27:52,450 Those that I've seen are used for patching operating systems. 1203 01:27:52,450 --> 01:27:55,450 Those can execute very slowly, but you don't run those very often. 1204 01:27:55,450 --> 01:27:57,180 It's only when you're doing patching, 1205 01:27:57,180 --> 01:27:59,450 and it's only the system manager who does those things, 1206 01:27:59,450 --> 01:28:01,840 so it's not really much of an issue. 1207 01:28:01,840 --> 01:28:06,980 Those that are hundreds of lines long actually execute fairly quickly. 1208 01:28:06,980 --> 01:28:10,540 Mentioning this here, what are those enhancements? 1209 01:28:10,540 --> 01:28:13,170 I've already mentioned a few of them--arrays, calculations, 1210 01:28:13,170 --> 01:28:20,540 the $( ) expression for calculations in the Bash shell, 1211 01:28:20,540 --> 01:28:23,050 the other kind of command substitution. 1212 01:28:23,050 --> 01:28:25,360 There are different kinds of testing commands 1213 01:28:25,360 --> 01:28:29,350 by which you can do conditional tests on the existence of a file or other things. 1214 01:28:29,350 --> 01:28:34,790 Last here, this command here. 1215 01:28:34,790 --> 01:28:38,480 What does this do, and why would anybody use it? 1216 01:28:51,170 --> 01:28:52,990 printenv variablename. 1217 01:28:52,990 --> 01:28:56,130 We know what printenv does. It tells us the value of a variable. 1218 01:28:56,130 --> 01:29:00,850 And printenv variablename won't tell us very much because there's no such variable. 1219 01:29:03,550 --> 01:29:05,120 Blank. 1220 01:29:05,120 --> 01:29:08,440 But let's give it something meaningful. 1221 01:29:13,420 --> 01:29:16,800 That's not there either. Okay. I guess I never defined that. 1222 01:29:16,800 --> 01:29:18,020 Let's just check my environment. 1223 01:29:18,020 --> 01:29:20,900 This is another command by which you can inspect your environment. 1224 01:29:20,900 --> 01:29:24,470 There is good old EDITOR, the one we saw before. 1225 01:29:42,360 --> 01:29:44,120 What does that do? 1226 01:29:44,120 --> 01:29:48,050 Here we have a backquote expression. 1227 01:29:48,050 --> 01:29:50,370 Remember this is the C-shell. 1228 01:29:50,370 --> 01:29:54,850 So printenv EDITOR will give us a value of EDITOR. It's vi. 1229 01:29:54,850 --> 01:29:59,790 And then it will set that value to variable a, the set command. 1230 01:29:59,790 --> 01:30:02,860 So now if I do echo $a, I get vi. 1231 01:30:02,860 --> 01:30:05,850 That doesn't seem terribly useful. 1232 01:30:05,850 --> 01:30:08,080 However, it actually does have a purpose. 1233 01:30:08,080 --> 01:30:12,260 Since we don't know whether a variable is a shell variable or an environment variable 1234 01:30:12,260 --> 01:30:16,280 by using the dollar sign evaluation syntax, we can use printenv 1235 01:30:16,280 --> 01:30:19,460 to make sure that it's an environment variable. 1236 01:30:19,460 --> 01:30:22,550 So if there were a shell variable editor, this wouldn't have gotten it. 1237 01:30:22,550 --> 01:30:25,640 This works only with the environment variable. 1238 01:30:25,640 --> 01:30:28,370 If there were a shell variable and I wanted its value, 1239 01:30:28,370 --> 01:30:29,980 I'd have to find some other way to do it. 1240 01:30:29,980 --> 01:30:33,530 One way to do that would be by doing set and piping. 1241 01:30:33,530 --> 01:30:36,130 This is one of the metacharacters, special characters. 1242 01:30:36,130 --> 01:30:38,370 It sends the output of set to something else. 1243 01:30:38,370 --> 01:30:40,650 Let's see what we might find there. 1244 01:30:40,650 --> 01:30:49,340 Nothing. Okay. Let's just see what's in there all together. 1245 01:30:49,340 --> 01:30:53,580 It was echo_style, the one I mentioned before. Okay, let's do that. 1246 01:31:02,460 --> 01:31:06,230 Remember I mentioned before, echo_style 1247 01:31:06,230 --> 01:31:08,410 determines the way the echo command will run. 1248 01:31:08,410 --> 01:31:10,940 bsd stands for Berkeley Standard Distribution. 1249 01:31:10,940 --> 01:31:13,200 This is the Berkeley Unix from the 1970s. 1250 01:31:13,200 --> 01:31:16,630 That's one of the ways that echo can run. 1251 01:31:16,630 --> 01:31:22,310 Setting echo_style to that value in the TC-shell will cause echo to behave that way. 1252 01:31:22,310 --> 01:31:27,670 So set does that, but set only gets shell variables. 1253 01:31:27,670 --> 01:31:35,430 It wouldn't find EDITOR, which is not a shell variable. 1254 01:31:36,870 --> 01:31:38,050 Nothing. 1255 01:31:38,050 --> 01:31:39,660 So that's one way of distinguishing them. 1256 01:31:39,660 --> 01:31:42,000 But the fact that you have to go through some strange command like that 1257 01:31:42,000 --> 01:31:45,500 to distinguish between shell variables or environment variables 1258 01:31:45,500 --> 01:31:49,970 shows the kind of impractical nature of the C-shell for some purposes. 1259 01:31:52,290 --> 01:31:57,960 And now, last and maybe least, this is the man pages. 1260 01:31:57,960 --> 01:32:03,190 Those of who you may know, the man is the command short for manual. 1261 01:32:03,190 --> 01:32:08,610 The man pages for the shells are hard to read. They're very long. 1262 01:32:08,610 --> 01:32:14,060 They're organized in a way that may make it difficult to find what you're looking for. 1263 01:32:14,060 --> 01:32:15,980 So if you're looking for something with a purpose, 1264 01:32:15,980 --> 01:32:20,050 you may not know if that purpose is a shell variable or something else, 1265 01:32:20,050 --> 01:32:21,630 so you may not know where to look for it. 1266 01:32:21,630 --> 01:32:25,030 You can look for various strings, but the strings are often repeated. 1267 01:32:25,030 --> 01:32:27,640 So it's generally hard to read. 1268 01:32:27,640 --> 01:32:33,810 We just looked at the TC-shell man page a little before to find the eval command. 1269 01:32:33,810 --> 01:32:36,610 Some things go faster. 1270 01:32:36,610 --> 01:32:38,860 One approach is to search for a string. 1271 01:32:38,860 --> 01:32:40,360 You can use the pager. 1272 01:32:40,360 --> 01:32:49,080 Pager has the slash to look for a command or a string inside a pager operation. 1273 01:32:49,080 --> 01:32:52,830 Man by default will use pagers, either be MORE or LESS. 1274 01:32:52,830 --> 01:32:56,560 I don't know if you're familiar with those, but those can show files bit by bit. 1275 01:32:56,560 --> 01:33:00,550 I've been using LESS to display these particular files we've got here. 1276 01:33:00,550 --> 01:33:03,300 You can search inside there. 1277 01:33:03,300 --> 01:33:04,880 You can try using different search strings. 1278 01:33:04,880 --> 01:33:08,420 Also man pages in different operating systems may not be the same. 1279 01:33:08,420 --> 01:33:11,130 They can be separate pages for csh and tcsh. 1280 01:33:11,130 --> 01:33:14,500 They're aren't on the Mac, but they might be if those are separate commands. 1281 01:33:14,500 --> 01:33:19,000 If sh doesn't really call Bash, there probably would be a separate man page. 1282 01:33:19,000 --> 01:33:25,820 Some systems have separate man pages just for the C-shell built-in commands. 1283 01:33:25,820 --> 01:33:30,250 Sometimes if you want to read a description of a built-in command 1284 01:33:30,250 --> 01:33:35,350 that's also in the path, like echo, you need to read the man page on that command on echo 1285 01:33:35,350 --> 01:33:37,610 to determine how it will work as a built-in command 1286 01:33:37,610 --> 01:33:39,760 even if you're not calling the built-in command. 1287 01:33:41,630 --> 01:33:46,090 That's a drawback of the operating system in general, not only for the shells, 1288 01:33:46,090 --> 01:33:50,710 although for the shells in particular the man pages are quite long, 1289 01:33:50,710 --> 01:33:56,180 partly because they've added useful features to them, which may be a positive. 1290 01:33:56,180 --> 01:34:00,290 Okay. Are there any questions? Any topics you want to bring up? 1291 01:34:00,290 --> 01:34:03,390 Anything relevant here? 1292 01:34:04,540 --> 01:34:07,100 Well, it's been very nice talking to you all. 1293 01:34:07,100 --> 01:34:09,690 I hope you got something out of this seminar 1294 01:34:09,690 --> 01:34:13,080 that will be useful for you in your future endeavors. 1295 01:34:17,330 --> 01:34:19,000 [CS50.TV]