WEBVTT

1
00:00:00.120 --> 00:00:03.799
<v Speaker 1>Imagine having a conversation where like, every time you pause

2
00:00:03.839 --> 00:00:06.839
<v Speaker 1>to take a breath, the person you're talking to completely

3
00:00:06.879 --> 00:00:08.359
<v Speaker 1>deletes your formatting.

4
00:00:08.000 --> 00:00:11.279
<v Speaker 2>Oh yeah, and just ignores half of what you actually meant, right, and.

5
00:00:11.240 --> 00:00:15.119
<v Speaker 1>Then mangles your sentence into something totally unrecognizable. I mean,

6
00:00:15.320 --> 00:00:17.760
<v Speaker 1>if you've ever typed a command into a computer terminal

7
00:00:17.800 --> 00:00:21.679
<v Speaker 1>and watched it instantly fail, you know exactly what I mean.

8
00:00:21.800 --> 00:00:23.000
<v Speaker 2>It's so frustrating.

9
00:00:23.079 --> 00:00:25.160
<v Speaker 1>It really is, because we tend to think of our

10
00:00:25.199 --> 00:00:29.160
<v Speaker 1>computers as these highly intuitive machines that you just want

11
00:00:29.199 --> 00:00:31.519
<v Speaker 1>to help us out. But when you strip away the

12
00:00:31.559 --> 00:00:35.479
<v Speaker 1>graphical interface, what you're left with is a blinking cursor

13
00:00:35.880 --> 00:00:37.640
<v Speaker 1>that is ruthlessly.

14
00:00:37.159 --> 00:00:41.000
<v Speaker 2>Literal, completely literal, and it's notoriously aggressive about how it

15
00:00:41.039 --> 00:00:43.560
<v Speaker 2>interprets your words. To a lot of people see that

16
00:00:43.600 --> 00:00:47.200
<v Speaker 2>blinking cursor the command line, and they just assume it's

17
00:00:47.200 --> 00:00:47.920
<v Speaker 2>a relic.

18
00:00:47.719 --> 00:00:49.840
<v Speaker 1>Like some archaic leftover from the nineteen.

19
00:00:49.600 --> 00:00:53.200
<v Speaker 2>Seventies, exactly like something we only keep around for it technicians.

20
00:00:53.479 --> 00:00:56.640
<v Speaker 2>But the command line is not a museum piece. It's

21
00:00:56.719 --> 00:01:01.640
<v Speaker 2>a programmable, highly efficient conversation with your operating system.

22
00:01:01.240 --> 00:01:03.840
<v Speaker 1>Which brings us to the core of our deep dive today.

23
00:01:04.040 --> 00:01:06.959
<v Speaker 1>I'm your host, and today we're pilling some incredible insights

24
00:01:07.120 --> 00:01:10.480
<v Speaker 1>from the Bash Cookbook, second edition by Carl Albing and

25
00:01:10.560 --> 00:01:11.359
<v Speaker 1>JP Vawson.

26
00:01:11.439 --> 00:01:13.200
<v Speaker 2>It's a fantastic resource.

27
00:01:12.840 --> 00:01:15.159
<v Speaker 1>It really is. And our mission today is to crack

28
00:01:15.200 --> 00:01:19.879
<v Speaker 1>open that dreaded cryptic command line interface. We're going to

29
00:01:19.920 --> 00:01:24.079
<v Speaker 1>decode the strange punctuation, learn how to pipe data around

30
00:01:24.319 --> 00:01:26.200
<v Speaker 1>like a well, like a master plumber.

31
00:01:26.239 --> 00:01:27.680
<v Speaker 2>Really, I love that analogy.

32
00:01:27.799 --> 00:01:31.120
<v Speaker 1>Thanks, and we'll discover why this text based tool is

33
00:01:31.159 --> 00:01:35.760
<v Speaker 1>still the absolute fastest shortcut to getting complex work done.

34
00:01:35.519 --> 00:01:38.599
<v Speaker 2>Because once you understand the grammar of this specific conversation,

35
00:01:38.719 --> 00:01:41.560
<v Speaker 2>it changes everything. It remembers your commands, lets you edit

36
00:01:41.560 --> 00:01:44.760
<v Speaker 2>them on the fly, and honestly, it can automate literally

37
00:01:44.799 --> 00:01:46.680
<v Speaker 2>any repetitive task you throw at it.

38
00:01:46.799 --> 00:01:48.959
<v Speaker 1>But before we start typing commands, we kind of need

39
00:01:48.959 --> 00:01:51.920
<v Speaker 1>to address what this black box actually is, because the

40
00:01:51.959 --> 00:01:55.239
<v Speaker 1>command line, or the shell as it's called, isn't actually

41
00:01:55.319 --> 00:01:59.239
<v Speaker 1>the operating system itself, which I have to admit blew

42
00:01:59.280 --> 00:02:01.599
<v Speaker 1>my mind a bit. I always assume the terminal window

43
00:02:01.719 --> 00:02:02.760
<v Speaker 1>was the core of the computer.

44
00:02:03.120 --> 00:02:06.640
<v Speaker 2>Oh, that's a really common misconception. But the separation between

45
00:02:06.680 --> 00:02:09.199
<v Speaker 2>the two is actually a foundational part of the original

46
00:02:09.319 --> 00:02:13.639
<v Speaker 2>Unix philosophy. How so well, in the earliest operating systems,

47
00:02:14.039 --> 00:02:18.000
<v Speaker 2>the user interface, the part that actually accepted your typed commands,

48
00:02:18.439 --> 00:02:21.840
<v Speaker 2>was hardwired straight into the operating system's core brain.

49
00:02:21.800 --> 00:02:24.280
<v Speaker 1>So they were bundled together, right, So if.

50
00:02:24.120 --> 00:02:26.479
<v Speaker 2>You wanted a better way to type commands for just

51
00:02:26.520 --> 00:02:29.759
<v Speaker 2>a new feature, you had to rewrite the entire operating

52
00:02:29.759 --> 00:02:30.560
<v Speaker 2>system to get.

53
00:02:30.439 --> 00:02:32.439
<v Speaker 1>It, which sounds a bit like trying to upgrade your

54
00:02:32.520 --> 00:02:35.000
<v Speaker 1>car's spearing wheel by replacing the entire engine.

55
00:02:35.080 --> 00:02:38.039
<v Speaker 2>That is a perfect analogy. It was incredibly inefficient, so

56
00:02:38.080 --> 00:02:42.039
<v Speaker 2>the creators of Unix separated them entirely. The operating system

57
00:02:42.080 --> 00:02:45.360
<v Speaker 2>handles the hardware, the memory, the heavy lifting, the engine

58
00:02:45.400 --> 00:02:48.120
<v Speaker 2>exactly the engine, and the shell is just a separate,

59
00:02:48.280 --> 00:02:51.719
<v Speaker 2>replaceable dashboard. Its only job is to listen to you

60
00:02:51.919 --> 00:02:54.719
<v Speaker 2>interpret your command and then pass it down to the engine.

61
00:02:55.080 --> 00:02:58.520
<v Speaker 2>And because it was a separate program, developers could write new,

62
00:02:58.919 --> 00:03:01.639
<v Speaker 2>better shells without ever touching the core system.

63
00:03:01.479 --> 00:03:03.599
<v Speaker 1>So you really could just swap out the dashboard whenever

64
00:03:03.639 --> 00:03:05.639
<v Speaker 1>you want. You could use shells with names like Crow

65
00:03:05.840 --> 00:03:07.439
<v Speaker 1>or KSh or Soush yep.

66
00:03:07.560 --> 00:03:08.919
<v Speaker 2>Absolutely, but today.

67
00:03:08.759 --> 00:03:12.120
<v Speaker 1>Our sources are focused entirely on Bash So why did

68
00:03:12.199 --> 00:03:15.400
<v Speaker 1>Bash become, you know, the universal rental car that everyone

69
00:03:15.439 --> 00:03:16.120
<v Speaker 1>knows how to drive.

70
00:03:16.439 --> 00:03:19.039
<v Speaker 2>It really comes down to a perfect storm of timing

71
00:03:19.080 --> 00:03:23.520
<v Speaker 2>and utility. Bash stands for the GNU born again.

72
00:03:23.360 --> 00:03:26.159
<v Speaker 1>Shell right, great pun by the way, Oh.

73
00:03:25.879 --> 00:03:29.439
<v Speaker 2>Programmers love their puns. But back in the late nineteen eighties,

74
00:03:29.520 --> 00:03:32.719
<v Speaker 2>the Gene project was trying to create a free, complete

75
00:03:32.719 --> 00:03:36.680
<v Speaker 2>operating system that followed PO six standards and posx.

76
00:03:36.280 --> 00:03:39.479
<v Speaker 1>Is essentially the universal rule book right for how Unix

77
00:03:39.479 --> 00:03:42.879
<v Speaker 1>systems should behave so software can run anywhere exactly.

78
00:03:43.080 --> 00:03:45.919
<v Speaker 2>They needed a standard shell for this free system, so

79
00:03:45.960 --> 00:03:49.199
<v Speaker 2>they built Bash by taking the heavy duty programming features

80
00:03:49.199 --> 00:03:53.080
<v Speaker 2>that developers required and combining them with the interactive conveniences

81
00:03:53.120 --> 00:03:55.120
<v Speaker 2>that everyday users wanted.

82
00:03:54.919 --> 00:03:56.800
<v Speaker 1>Things like just hitting the up arrow to see your

83
00:03:56.879 --> 00:03:57.439
<v Speaker 1>last command.

84
00:03:57.560 --> 00:03:59.879
<v Speaker 2>Yes, small things that made a huge difference.

85
00:04:00.159 --> 00:04:02.360
<v Speaker 1>Well, it clearly won the war. I mean, it's the

86
00:04:02.400 --> 00:04:06.159
<v Speaker 1>default on almost all Linux distributions historically, the default on

87
00:04:06.280 --> 00:04:09.520
<v Speaker 1>mac os, and you can even install it on Windows

88
00:04:09.560 --> 00:04:12.800
<v Speaker 1>through the Windows subsystem. For a Linux, it's everywhere. So

89
00:04:12.840 --> 00:04:15.439
<v Speaker 1>you learn Bash and suddenly you have a passport to

90
00:04:15.479 --> 00:04:17.279
<v Speaker 1>talk to almost any machine on the planet.

91
00:04:17.360 --> 00:04:20.279
<v Speaker 2>You do, but to speak the language you first have

92
00:04:20.360 --> 00:04:23.560
<v Speaker 2>to read the room. When you open that terminal, you're

93
00:04:23.639 --> 00:04:27.000
<v Speaker 2>greeted by a prompt, and that prompt usually ends with

94
00:04:27.040 --> 00:04:30.800
<v Speaker 2>a specific symbol, often a dollar sign or a hash symbol. Right,

95
00:04:30.959 --> 00:04:34.079
<v Speaker 2>and that tiny character is actually screaming a warning at

96
00:04:34.120 --> 00:04:35.720
<v Speaker 2>you if you know how to listen.

97
00:04:35.879 --> 00:04:38.759
<v Speaker 1>So let's decode that for the listener. If my prompt

98
00:04:38.839 --> 00:04:41.720
<v Speaker 1>ends in a dollar sign, the shell is basically saying

99
00:04:41.879 --> 00:04:45.279
<v Speaker 1>you are a regular user, you have normal safe permissions exactly.

100
00:04:45.319 --> 00:04:46.800
<v Speaker 1>But if it ends in a hash sign like the

101
00:04:46.839 --> 00:04:48.680
<v Speaker 1>number symbol, it's saying you are.

102
00:04:48.680 --> 00:04:52.079
<v Speaker 2>Root, the all powerful system administrator. As route, there are

103
00:04:52.120 --> 00:04:54.160
<v Speaker 2>no safety rails whatsoever. You can do.

104
00:04:54.160 --> 00:04:57.199
<v Speaker 1>Anything, which also means you can accidentally delete the entire

105
00:04:57.240 --> 00:04:58.680
<v Speaker 1>hard drive with a single typo.

106
00:04:58.879 --> 00:05:01.480
<v Speaker 2>Yep, seeing that hash sign is your visual queue to

107
00:05:01.600 --> 00:05:03.639
<v Speaker 2>double check every single keystroke.

108
00:05:03.879 --> 00:05:06.519
<v Speaker 1>Okay, So the prompt tells us who we are. It

109
00:05:06.560 --> 00:05:08.360
<v Speaker 1>also usually tries and tell us where we are in

110
00:05:08.399 --> 00:05:11.800
<v Speaker 1>the computer's folder structure. But the cookbook points out something

111
00:05:11.879 --> 00:05:13.480
<v Speaker 1>incredibly sneaky.

112
00:05:13.040 --> 00:05:14.319
<v Speaker 2>Here, oh about the paths.

113
00:05:14.560 --> 00:05:18.439
<v Speaker 1>Yeah, the prompt sometimes lies to you, or at least

114
00:05:18.600 --> 00:05:20.959
<v Speaker 1>it gives you an illusion like, wait, why would my

115
00:05:21.000 --> 00:05:22.920
<v Speaker 1>computer lie to me about what? Folder I'm in.

116
00:05:23.040 --> 00:05:25.160
<v Speaker 2>Well, it's not so much lying as it is keeping

117
00:05:25.240 --> 00:05:28.160
<v Speaker 2>up a facade that you created. Okay, fair, Think about

118
00:05:28.199 --> 00:05:31.120
<v Speaker 2>shortcuts on your desktop. In the Unix world, these are

119
00:05:31.160 --> 00:05:34.079
<v Speaker 2>called symbolic links. You might have a folder on your

120
00:05:34.079 --> 00:05:37.639
<v Speaker 2>desktop called photos, but the actual files are stored deep

121
00:05:37.680 --> 00:05:40.879
<v Speaker 2>inside some external hard drive. If you navigate into that

122
00:05:40.920 --> 00:05:45.600
<v Speaker 2>desktop folder and use the PW beauty command print working directory,

123
00:05:46.279 --> 00:05:49.240
<v Speaker 2>the shell might just say you are on the desktop.

124
00:05:48.879 --> 00:05:50.480
<v Speaker 1>Because that's the path I took to get there.

125
00:05:50.519 --> 00:05:54.120
<v Speaker 2>Precisely, If you type pdbudd dash L, it gives you

126
00:05:54.120 --> 00:05:57.160
<v Speaker 2>your logical path that's where you think you are based

127
00:05:57.160 --> 00:05:58.519
<v Speaker 2>on the shortcuts you followed.

128
00:05:58.600 --> 00:05:58.920
<v Speaker 1>Got it.

129
00:05:59.399 --> 00:06:01.759
<v Speaker 2>But if if you need to know where those files

130
00:06:01.800 --> 00:06:05.920
<v Speaker 2>physically reside on the spinning disc, you use PWD dash

131
00:06:05.959 --> 00:06:10.279
<v Speaker 2>p P for physical Right. The dash P strips away

132
00:06:10.319 --> 00:06:13.800
<v Speaker 2>all the illusions and reveals the true physical path.

133
00:06:14.079 --> 00:06:17.560
<v Speaker 1>That distinction alone can save like hours of troubleshooting. Yeah,

134
00:06:17.600 --> 00:06:21.360
<v Speaker 1>but here is where navigating gets truly dangerous. We all

135
00:06:21.399 --> 00:06:24.240
<v Speaker 1>have hidden files on our computers right. Oh yes, and

136
00:06:24.279 --> 00:06:27.160
<v Speaker 1>in Unix they're called dot files because their names literally

137
00:06:27.240 --> 00:06:29.480
<v Speaker 1>just start with a period exactly. So if I want

138
00:06:29.480 --> 00:06:31.839
<v Speaker 1>to see them, my instinct as a user is to

139
00:06:31.920 --> 00:06:35.040
<v Speaker 1>use a wildcard. I know what asterisk means everything, so

140
00:06:35.120 --> 00:06:38.079
<v Speaker 1>I figured I type the list command ls followed by

141
00:06:38.079 --> 00:06:40.279
<v Speaker 1>dot asterisk. You have to see all my hidden dot

142
00:06:40.279 --> 00:06:43.959
<v Speaker 1>file which seems totally logical, right, But the cookbook says

143
00:06:44.079 --> 00:06:47.959
<v Speaker 1>this will cause a catastrophic wall of text. Why if

144
00:06:47.959 --> 00:06:51.800
<v Speaker 1>the asterisk means everything, shouldn't dot asterisk just list my

145
00:06:51.879 --> 00:06:52.639
<v Speaker 1>hidden files?

146
00:06:52.879 --> 00:06:55.439
<v Speaker 2>This is such a classic trap, and it introduces a

147
00:06:55.480 --> 00:06:58.639
<v Speaker 2>process called globbing, which is how the shell actually expands

148
00:06:58.680 --> 00:07:02.319
<v Speaker 2>wildcards wlobbing. Okay, so the asterisk does mean any characters

149
00:07:02.439 --> 00:07:05.639
<v Speaker 2>zero or more times. You're totally correct that dot asterisk

150
00:07:05.759 --> 00:07:07.399
<v Speaker 2>matches any file starting with a dot.

151
00:07:07.480 --> 00:07:08.519
<v Speaker 1>Okay, so what's the problem.

152
00:07:08.600 --> 00:07:11.240
<v Speaker 2>The danger lies in how the Unix filesystem is built.

153
00:07:11.600 --> 00:07:15.480
<v Speaker 2>In every single directory without exception, there are two invisible folders.

154
00:07:15.959 --> 00:07:18.480
<v Speaker 2>One is named with a single dot, which is a

155
00:07:18.519 --> 00:07:21.879
<v Speaker 2>shortcut representing the directory you are currently in, ah right,

156
00:07:21.959 --> 00:07:24.600
<v Speaker 2>and the other is named with two dots dot dot,

157
00:07:24.879 --> 00:07:28.040
<v Speaker 2>which is a shortcut representing the parent directory exactly one

158
00:07:28.120 --> 00:07:28.680
<v Speaker 2>level above.

159
00:07:28.759 --> 00:07:29.720
<v Speaker 1>Oh, I see where this is going.

160
00:07:29.839 --> 00:07:33.399
<v Speaker 2>Yeah, when you type l's dot asterisk, the shell aggressively

161
00:07:33.439 --> 00:07:37.040
<v Speaker 2>expands that wildcard before the l's command even runs. Oh no,

162
00:07:37.120 --> 00:07:39.959
<v Speaker 2>it matches your hidden files, sure, but it also matches

163
00:07:40.120 --> 00:07:42.759
<v Speaker 2>the single dot and the double dot. So the shell

164
00:07:42.879 --> 00:07:45.920
<v Speaker 2>tells the l's command, please list the contents of the

165
00:07:46.000 --> 00:07:48.720
<v Speaker 2>hidden files, and the contents of the current folder, and

166
00:07:48.800 --> 00:07:51.319
<v Speaker 2>the entire contents of the folder above this.

167
00:07:51.240 --> 00:07:53.839
<v Speaker 1>One, which could be my entire home direction exactly. It

168
00:07:53.839 --> 00:07:56.600
<v Speaker 1>would just dump thousands of files onto my screen endlessly.

169
00:07:57.040 --> 00:08:00.240
<v Speaker 1>So how do we actually isolate the hidden files without

170
00:08:00.279 --> 00:08:02.160
<v Speaker 1>triggering an absolute avalanche?

171
00:08:02.240 --> 00:08:05.800
<v Speaker 2>The cookbook provides a brilliantly precise piece of syntax.

172
00:08:05.879 --> 00:08:06.040
<v Speaker 1>Or this.

173
00:08:06.519 --> 00:08:11.040
<v Speaker 2>You type dot, dot, bracket, exclamation point, dot, close bracket

174
00:08:11.120 --> 00:08:11.680
<v Speaker 2>as risk.

175
00:08:11.959 --> 00:08:14.680
<v Speaker 1>Okay, let me translate that out of alphabet soup a dot,

176
00:08:15.079 --> 00:08:18.480
<v Speaker 1>then an open bracket, an exclamation point, another dot, a

177
00:08:18.519 --> 00:08:21.959
<v Speaker 1>closed bracket, and finally an asterisk. What is the logic

178
00:08:22.040 --> 00:08:22.519
<v Speaker 1>behind that?

179
00:08:23.240 --> 00:08:27.199
<v Speaker 2>So brackets let you define a specific pool of allowed characters.

180
00:08:27.639 --> 00:08:30.040
<v Speaker 2>But when you put an exclamation point right inside the

181
00:08:30.079 --> 00:08:32.960
<v Speaker 2>opening bracket, it acts as a negator, like saying not

182
00:08:33.159 --> 00:08:37.639
<v Speaker 2>this exactly. It means absolutely not this character. So that

183
00:08:37.679 --> 00:08:40.879
<v Speaker 2>whole sequence translates to find a file that starts with

184
00:08:40.960 --> 00:08:43.440
<v Speaker 2>a dot. Now make sure the very next character is

185
00:08:43.559 --> 00:08:46.840
<v Speaker 2>absolutely not a dot. After that, the asterisk says you

186
00:08:46.879 --> 00:08:50.360
<v Speaker 2>can grab whatever is left. It perfectly targets your hidden

187
00:08:50.399 --> 00:08:54.000
<v Speaker 2>files while explicitly ignoring the single and double dot directories.

188
00:08:54.080 --> 00:08:57.200
<v Speaker 1>That is surgically precise, okay, and it brings us to

189
00:08:57.279 --> 00:09:00.840
<v Speaker 1>a massive realization about Bash. How you format your text

190
00:09:01.000 --> 00:09:03.559
<v Speaker 1>matters just as much as the command itself. Oh completely,

191
00:09:03.639 --> 00:09:07.159
<v Speaker 1>Because that shell is an aggressive listener. It intercepts parses

192
00:09:07.200 --> 00:09:10.000
<v Speaker 1>and modifies your words before it ever passes them to

193
00:09:10.039 --> 00:09:11.480
<v Speaker 1>the actual program you're trying to run.

194
00:09:11.799 --> 00:09:14.960
<v Speaker 2>That aggressive listening is exactly why spacing can drive new

195
00:09:15.039 --> 00:09:18.279
<v Speaker 2>users crazy. The shell uses spaces purely to figure out

196
00:09:18.279 --> 00:09:20.320
<v Speaker 2>where one argument ends and another begins.

197
00:09:20.720 --> 00:09:23.159
<v Speaker 1>Right, So, if I use the echo command, which just

198
00:09:23.240 --> 00:09:25.720
<v Speaker 1>prints whatever you type back to the screen, A type echo,

199
00:09:26.000 --> 00:09:28.559
<v Speaker 1>then the word this, Then I hit the space bar

200
00:09:28.639 --> 00:09:31.559
<v Speaker 1>ten times, then the word was, ten more spaces, and

201
00:09:31.600 --> 00:09:33.960
<v Speaker 1>the word spaced. What comes out on my screen is

202
00:09:34.039 --> 00:09:36.440
<v Speaker 1>just this was spaced with single spaces.

203
00:09:36.600 --> 00:09:38.200
<v Speaker 2>It looks completely normal.

204
00:09:38.360 --> 00:09:41.320
<v Speaker 1>Yeah, the shell just ate all my custom formatting.

205
00:09:40.960 --> 00:09:43.440
<v Speaker 2>Because it didn't see ten spaces. It just saw boundaries.

206
00:09:43.759 --> 00:09:45.840
<v Speaker 2>It grabbed the word this, the word was, and the

207
00:09:45.879 --> 00:09:49.159
<v Speaker 2>word spaced, packaged them up and handed those three neat

208
00:09:49.200 --> 00:09:51.600
<v Speaker 2>little boxes to the echo command. It threw all the

209
00:09:51.600 --> 00:09:53.559
<v Speaker 2>extra white space straight in the trash.

210
00:09:53.759 --> 00:09:55.879
<v Speaker 1>So if you want to protect your formatting from the

211
00:09:55.919 --> 00:09:59.639
<v Speaker 1>shell's aggressive interpretation, you have to lock it away using quotes.

212
00:09:59.759 --> 00:10:01.679
<v Speaker 2>Yes, quoting is essential, and.

213
00:10:01.679 --> 00:10:05.159
<v Speaker 1>Here we enter the absolute tyranny of quoting in Bash

214
00:10:05.559 --> 00:10:09.320
<v Speaker 1>because there is a massive fundamental difference between single quotes

215
00:10:09.320 --> 00:10:12.360
<v Speaker 1>and double quotes. I like to think of single quotes

216
00:10:12.399 --> 00:10:15.679
<v Speaker 1>like sealing your text inside a welded steel lock box.

217
00:10:16.080 --> 00:10:17.399
<v Speaker 2>That's a good way to look at it, right.

218
00:10:17.639 --> 00:10:20.759
<v Speaker 1>The shell physically cannot look inside. It just hands the

219
00:10:20.799 --> 00:10:24.240
<v Speaker 1>heavy box directly to the program. But double quotes are

220
00:10:24.240 --> 00:10:28.039
<v Speaker 1>like putting your text in a clear plastic bag. It

221
00:10:28.159 --> 00:10:30.919
<v Speaker 1>keeps the spaces together, but the shell can still peer

222
00:10:30.919 --> 00:10:32.879
<v Speaker 1>through the plastic and mess with the contents.

223
00:10:33.240 --> 00:10:37.600
<v Speaker 2>That is an excellent visualization. Double quotes protect your white space,

224
00:10:38.080 --> 00:10:41.679
<v Speaker 2>but they still allow the shell to perform substitutions. It'll

225
00:10:41.679 --> 00:10:45.639
<v Speaker 2>look inside that clear plastic bag for special characters like

226
00:10:45.720 --> 00:10:49.559
<v Speaker 2>dollar signs and exclamation points and actually try to execute them.

227
00:10:49.960 --> 00:10:52.639
<v Speaker 1>The cookbook has this hilarious example of how badly this

228
00:10:52.679 --> 00:10:55.759
<v Speaker 1>can go wrong. Yeah, imagine you want to print a simple,

229
00:10:55.840 --> 00:10:59.960
<v Speaker 1>frustrated sentence to the screen. A coffee is five dollars

230
00:11:00.519 --> 00:11:01.480
<v Speaker 1>with a dollar sign.

231
00:11:01.759 --> 00:11:03.039
<v Speaker 2>Very relatable script.

232
00:11:02.879 --> 00:11:05.279
<v Speaker 1>If you put that in double quotes, echo, double quote,

233
00:11:05.639 --> 00:11:08.960
<v Speaker 1>A coffee is dollar sign five, question mark, exclamation point,

234
00:11:09.120 --> 00:11:11.559
<v Speaker 1>double quote. It fails spectacularly.

235
00:11:11.759 --> 00:11:14.840
<v Speaker 2>It fails on two separate fronts. Actually, first, the shell

236
00:11:14.919 --> 00:11:17.360
<v Speaker 2>looks through the double quotes and spots the dollar sign

237
00:11:17.559 --> 00:11:20.679
<v Speaker 2>in bash. A dollar sign means you were calling a variable,

238
00:11:20.919 --> 00:11:23.679
<v Speaker 2>so it looks for a variable named five. Unless you

239
00:11:23.759 --> 00:11:27.360
<v Speaker 2>specifically created one. That variable doesn't exist, So the shell

240
00:11:27.440 --> 00:11:29.519
<v Speaker 2>just replaces dollar sign five with nothing.

241
00:11:29.799 --> 00:11:31.799
<v Speaker 1>It just vanishes Rea coffee.

242
00:11:31.440 --> 00:11:35.440
<v Speaker 2>Poof exactly, but the exclamation point makes it so much worse.

243
00:11:35.799 --> 00:11:38.600
<v Speaker 2>An exclamation point triggers history substitution.

244
00:11:38.879 --> 00:11:40.919
<v Speaker 1>Wait history, Yeah.

245
00:11:40.679 --> 00:11:43.320
<v Speaker 2>The shell tries to look back in your command history

246
00:11:43.360 --> 00:11:47.679
<v Speaker 2>for a previous command starting with whatever follows the exclamation mark.

247
00:11:48.159 --> 00:11:50.679
<v Speaker 2>It attempts to pull that old command right into your

248
00:11:50.720 --> 00:11:54.200
<v Speaker 2>current sentence, fails to find a match, and throws a

249
00:11:54.240 --> 00:11:57.799
<v Speaker 2>confusing event not found error. Oh man, your script just

250
00:11:57.840 --> 00:11:59.000
<v Speaker 2>completely crashes.

251
00:11:59.360 --> 00:12:03.159
<v Speaker 1>So learning to quote properly is literally the difference between

252
00:12:03.159 --> 00:12:05.559
<v Speaker 1>a working script and a script that makes you want

253
00:12:05.559 --> 00:12:06.840
<v Speaker 1>to throw your laptop out.

254
00:12:06.679 --> 00:12:07.720
<v Speaker 2>A window without a doubt.

255
00:12:07.799 --> 00:12:10.200
<v Speaker 1>If you just wrap that exact same sentence in single

256
00:12:10.279 --> 00:12:13.159
<v Speaker 1>quote steel lock box quotes, the shell wouldn't look for

257
00:12:13.240 --> 00:12:15.919
<v Speaker 1>variables or history. It would just print the sentence.

258
00:12:16.440 --> 00:12:19.559
<v Speaker 2>Understanding who is intercepting your commands is half the battle here,

259
00:12:19.799 --> 00:12:22.000
<v Speaker 2>and that also applies to the commands themselves. What do

260
00:12:22.039 --> 00:12:24.519
<v Speaker 2>you mean, Well, sometimes you type a command and you

261
00:12:24.639 --> 00:12:26.919
<v Speaker 2>don't actually know if you're talking to a program installed

262
00:12:26.960 --> 00:12:29.600
<v Speaker 2>in your hard drive or a feature built directly into

263
00:12:29.639 --> 00:12:30.720
<v Speaker 2>the Bash shell itself.

264
00:12:30.879 --> 00:12:33.519
<v Speaker 1>Ah like the difference between an external executable and a

265
00:12:33.559 --> 00:12:36.600
<v Speaker 1>built in exactly. For instance, the CD command to change directories,

266
00:12:36.639 --> 00:12:39.559
<v Speaker 1>that's a built in part of Bash, but a text

267
00:12:39.679 --> 00:12:43.639
<v Speaker 1>processing tool like AC is an external program. So how

268
00:12:43.639 --> 00:12:45.480
<v Speaker 1>do we reveal the truth about a command?

269
00:12:46.360 --> 00:12:49.919
<v Speaker 2>You ask the shell directly using the type or which commands? Okay,

270
00:12:50.000 --> 00:12:53.200
<v Speaker 2>if you type type CD, the shell will explicitly reply

271
00:12:53.480 --> 00:12:56.080
<v Speaker 2>CD is a shell built in. But if you type

272
00:12:56.120 --> 00:12:59.120
<v Speaker 2>type OC, it will give you the physical filepath on

273
00:12:59.159 --> 00:13:01.519
<v Speaker 2>your hard drive, pointing to the OUC program.

274
00:13:01.720 --> 00:13:03.039
<v Speaker 1>Why does that matter so much?

275
00:13:03.200 --> 00:13:06.919
<v Speaker 2>This becomes crucial when writing scripts for other people. Built

276
00:13:06.960 --> 00:13:09.960
<v Speaker 2>ins will always be there, but external programs might not

277
00:13:10.039 --> 00:13:11.960
<v Speaker 2>be installed on your coworker's machine.

278
00:13:12.120 --> 00:13:15.080
<v Speaker 1>Oh that makes total sense. Okay, So we've covered navigating

279
00:13:15.120 --> 00:13:18.039
<v Speaker 1>the system and formatting our commands so the shell doesn't

280
00:13:18.080 --> 00:13:20.600
<v Speaker 1>butcher them. Now let's talk about.

281
00:13:20.360 --> 00:13:21.639
<v Speaker 2>The results the output.

282
00:13:21.799 --> 00:13:24.879
<v Speaker 1>Right, we've essentially built a megaphone for our programs, but

283
00:13:24.919 --> 00:13:28.039
<v Speaker 1>where do they shout their answers. This brings us to

284
00:13:28.080 --> 00:13:33.039
<v Speaker 1>the fundamental magic of the Unix operating system IO redirection.

285
00:13:32.919 --> 00:13:37.120
<v Speaker 2>Input output redirection. In Unix, everything looks like a file.

286
00:13:37.519 --> 00:13:41.399
<v Speaker 2>A text document is a file, but your keyboard is

287
00:13:41.440 --> 00:13:44.159
<v Speaker 2>also treated as a file. Your screen is treated as

288
00:13:44.159 --> 00:13:44.919
<v Speaker 2>a file.

289
00:13:45.120 --> 00:13:47.799
<v Speaker 1>Which is such a brilliant abstraction. I don't need to

290
00:13:47.840 --> 00:13:50.440
<v Speaker 1>know how to write complex code to display pixels on

291
00:13:50.480 --> 00:13:53.559
<v Speaker 1>a monitor, or write drivers to interface with a USB

292
00:13:53.679 --> 00:13:56.360
<v Speaker 1>flash drive, not at all. The shell handles all that

293
00:13:56.440 --> 00:13:59.960
<v Speaker 1>translation using the greater than symbol the right pointing bracket.

294
00:14:00.120 --> 00:14:03.480
<v Speaker 2>Exactly, if you type echo hello greater than output dot txt,

295
00:14:03.960 --> 00:14:06.440
<v Speaker 2>the shell intercepts the output before it ever reaches your

296
00:14:06.440 --> 00:14:09.720
<v Speaker 2>screen and channels it directly into that text file instead.

297
00:14:10.039 --> 00:14:12.440
<v Speaker 1>But if I run that exact command again, it wipes

298
00:14:12.480 --> 00:14:14.399
<v Speaker 1>out whatever was already in that file and replaces it.

299
00:14:14.559 --> 00:14:16.200
<v Speaker 2>Rate it does it overwrites it completely.

300
00:14:16.639 --> 00:14:18.480
<v Speaker 1>So to safely add to the end of the file,

301
00:14:18.519 --> 00:14:21.039
<v Speaker 1>I have to use two brackets greater than greater than,

302
00:14:21.519 --> 00:14:23.440
<v Speaker 1>which tells the shell to append the data.

303
00:14:23.559 --> 00:14:26.519
<v Speaker 2>Appending is safer, yes, but if you want a true

304
00:14:26.559 --> 00:14:30.159
<v Speaker 2>safety net, Bash actually offers a brilliant feature called no.

305
00:14:30.240 --> 00:14:32.840
<v Speaker 1>Clobber no clawber. Great name it is.

306
00:14:33.320 --> 00:14:36.960
<v Speaker 2>By typing set dash no clawber, you instruct the shell

307
00:14:37.039 --> 00:14:41.240
<v Speaker 2>to aggressively protect existing files. If you accidentally use a

308
00:14:41.240 --> 00:14:43.440
<v Speaker 2>single grater then and point it out a file that

309
00:14:43.480 --> 00:14:46.080
<v Speaker 2>already has data in it, the shell will refuse to

310
00:14:46.120 --> 00:14:48.039
<v Speaker 2>overwrite it and throw an error instead.

311
00:14:48.399 --> 00:14:51.600
<v Speaker 1>No clawber is amazing. It really saves you from yourself.

312
00:14:51.720 --> 00:14:53.879
<v Speaker 1>But what if I really want to overwrite the file

313
00:14:54.000 --> 00:14:56.159
<v Speaker 1>like I've got no clawber turned on, but I know

314
00:14:56.200 --> 00:14:59.159
<v Speaker 1>what I'm doing and this specific file needs to be

315
00:14:59.200 --> 00:14:59.799
<v Speaker 1>wiped clean.

316
00:15:00.000 --> 00:15:02.559
<v Speaker 2>When you use the do it anyway operator the overrite right,

317
00:15:02.759 --> 00:15:05.279
<v Speaker 2>you type the greater than symbol followed immediately by a

318
00:15:05.320 --> 00:15:08.840
<v Speaker 2>vertical bar. That syntax tells the show I know the

319
00:15:08.879 --> 00:15:11.600
<v Speaker 2>safety is on, but bypass no clubber for just this

320
00:15:11.720 --> 00:15:12.919
<v Speaker 2>one specific command.

321
00:15:13.159 --> 00:15:16.399
<v Speaker 1>It's the manual override switch. Now, speaking of redirection, there

322
00:15:16.480 --> 00:15:18.440
<v Speaker 1>is a quicky behavior with the eel's command. That always

323
00:15:18.480 --> 00:15:18.960
<v Speaker 1>confused me.

324
00:15:19.080 --> 00:15:20.240
<v Speaker 2>Oh the column formatting.

325
00:15:20.519 --> 00:15:24.159
<v Speaker 1>Yes, when I type l's in my terminal, it formats

326
00:15:24.200 --> 00:15:27.480
<v Speaker 1>the files into a beautiful, neat grid across my screen.

327
00:15:28.320 --> 00:15:31.360
<v Speaker 1>But the second I redirect it to a file, l's

328
00:15:31.600 --> 00:15:34.159
<v Speaker 1>greater than save dot out and then open that file,

329
00:15:34.480 --> 00:15:38.399
<v Speaker 1>the grid is gone. It's just one long, single column

330
00:15:38.480 --> 00:15:39.240
<v Speaker 1>of file names.

331
00:15:40.039 --> 00:15:43.279
<v Speaker 2>Why does the formating completely change just because I send

332
00:15:43.320 --> 00:15:43.879
<v Speaker 2>it to a file.

333
00:15:44.039 --> 00:15:46.399
<v Speaker 1>That's actually by design, and it shows how smart these

334
00:15:46.440 --> 00:15:50.399
<v Speaker 1>tools are. Programs can actually detect the environment they're talking to. Really, Yeah,

335
00:15:50.559 --> 00:15:53.080
<v Speaker 1>The cell's command checks to see if its output is

336
00:15:53.120 --> 00:15:55.519
<v Speaker 1>going to a screen, a terminal, or if it is

337
00:15:55.519 --> 00:15:58.320
<v Speaker 1>being redirected into a file. If it detects a screen,

338
00:15:58.639 --> 00:16:01.279
<v Speaker 1>it assumes a human is reading it, so it formats

339
00:16:01.279 --> 00:16:03.279
<v Speaker 1>it into columns to save visual space.

340
00:16:03.440 --> 00:16:03.919
<v Speaker 2>Makes sense.

341
00:16:04.200 --> 00:16:06.600
<v Speaker 1>But if it detects a file, it assumes another computer

342
00:16:06.679 --> 00:16:09.519
<v Speaker 1>program might need to read that list later, and programs

343
00:16:09.600 --> 00:16:12.759
<v Speaker 1>strongly prefer reading data one line at a time, so

344
00:16:12.799 --> 00:16:15.360
<v Speaker 1>it automatically switches to a single column format.

345
00:16:15.440 --> 00:16:17.879
<v Speaker 2>It literally changes its behavior based on the audience.

346
00:16:18.320 --> 00:16:21.960
<v Speaker 1>That leads perfectly into a classic frustration every learner faces

347
00:16:21.960 --> 00:16:25.440
<v Speaker 1>with redirection. I remember I tried to redirect my compiler

348
00:16:25.559 --> 00:16:28.759
<v Speaker 1>errors to a file. I type my compile command then

349
00:16:28.840 --> 00:16:30.480
<v Speaker 1>greater than errors dot txt.

350
00:16:30.840 --> 00:16:31.759
<v Speaker 2>Let me guess yeap.

351
00:16:32.639 --> 00:16:34.960
<v Speaker 1>When I hit enter, the error is still spammed all

352
00:16:34.960 --> 00:16:37.840
<v Speaker 1>over my screen, and when I checked errors dot txt

353
00:16:38.360 --> 00:16:41.960
<v Speaker 1>it was completely empty. Why did the shell catch the errors?

354
00:16:42.840 --> 00:16:46.200
<v Speaker 2>This requires looking under the hood at file descriptors. When

355
00:16:46.200 --> 00:16:49.240
<v Speaker 2>a program runs in Unix, it opens three invisible channels

356
00:16:49.240 --> 00:16:51.600
<v Speaker 2>for data to flow through. They are numbered zero, one,

357
00:16:51.840 --> 00:16:52.200
<v Speaker 2>and two.

358
00:16:52.360 --> 00:16:54.080
<v Speaker 1>The channels zero, one and two okay.

359
00:16:54.200 --> 00:16:57.159
<v Speaker 2>Channel zero is standard input where the program gets its data,

360
00:16:57.200 --> 00:17:00.519
<v Speaker 2>typically your keyboard. Channel one is standard output. This is

361
00:17:00.600 --> 00:17:03.919
<v Speaker 2>the normal expected output of a program right and it

362
00:17:04.000 --> 00:17:06.839
<v Speaker 2>is buffered, meaning it saves up chunks of text and

363
00:17:06.880 --> 00:17:09.319
<v Speaker 2>sends them all at once for efficiency and channel two.

364
00:17:09.440 --> 00:17:12.240
<v Speaker 2>Channel two is standard error. This is a completely separate

365
00:17:12.240 --> 00:17:17.799
<v Speaker 2>pipeline dedicated exclusively to error messages, and crucially, it is unbuffered.

366
00:17:17.400 --> 00:17:19.359
<v Speaker 1>Meaning it doesn't wait exactly.

367
00:17:19.440 --> 00:17:23.119
<v Speaker 2>It spits text out instantly, character by character. That way,

368
00:17:23.200 --> 00:17:26.160
<v Speaker 2>if the program crashes dramatically and takes the system down

369
00:17:26.200 --> 00:17:28.640
<v Speaker 2>with it, the error message still makes it to your

370
00:17:28.680 --> 00:17:30.079
<v Speaker 2>screen before the lights go out.

371
00:17:30.279 --> 00:17:33.119
<v Speaker 1>So if channel one is standardshipping via the loading dock.

372
00:17:33.279 --> 00:17:36.559
<v Speaker 1>Channel two is like an emergency red phone line that

373
00:17:36.680 --> 00:17:40.400
<v Speaker 1>bypasses the loading dock entirely, so the error gets out instantly.

374
00:17:40.599 --> 00:17:42.359
<v Speaker 2>That's a great way to put it. When you used

375
00:17:42.359 --> 00:17:46.000
<v Speaker 2>a simple greater than symbol, you are only redirecting channel one.

376
00:17:46.720 --> 00:17:49.400
<v Speaker 2>Oh right, A single grater then is just shorthand for

377
00:17:49.440 --> 00:17:53.039
<v Speaker 2>one greater. Then you successfully redirected the normal output to

378
00:17:53.079 --> 00:17:56.160
<v Speaker 2>your file which was empty because your compiler failed. But

379
00:17:56.240 --> 00:17:59.319
<v Speaker 2>the errors were traveling down channel two, the red phone line,

380
00:17:59.359 --> 00:18:01.160
<v Speaker 2>which was still point it's straight at your screen.

381
00:18:01.319 --> 00:18:02.440
<v Speaker 1>So how do I catch channel two?

382
00:18:02.599 --> 00:18:05.079
<v Speaker 2>If you just want the errors, you pipe two greater

383
00:18:05.119 --> 00:18:09.079
<v Speaker 2>than errors dot txt, but usually you want both to

384
00:18:09.160 --> 00:18:12.000
<v Speaker 2>catch normal output A and D errors in the same file.

385
00:18:12.079 --> 00:18:16.279
<v Speaker 2>You'll often see this classic slightly cryptic syntax greater than

386
00:18:16.359 --> 00:18:18.920
<v Speaker 2>errors dot txt two greater than ampersan one.

387
00:18:19.160 --> 00:18:20.960
<v Speaker 1>Okay, let's break that down because it looks like a

388
00:18:21.000 --> 00:18:25.799
<v Speaker 1>typo to me. Greater than errors dot txt space two

389
00:18:26.640 --> 00:18:28.400
<v Speaker 1>greater than ampersand one.

390
00:18:28.960 --> 00:18:32.680
<v Speaker 2>Think of it like aiming two water hoses. The first part,

391
00:18:32.720 --> 00:18:36.400
<v Speaker 2>greater than errors dot txt points hose one standard output

392
00:18:36.480 --> 00:18:39.200
<v Speaker 2>into a bucket called errors dot txt.

393
00:18:39.680 --> 00:18:41.400
<v Speaker 1>Okay, hose one is in the bucket.

394
00:18:41.440 --> 00:18:44.880
<v Speaker 2>The second part two greater than ampersan one grabs hose

395
00:18:44.960 --> 00:18:47.880
<v Speaker 2>to standard error the ampersand is the key. Here it

396
00:18:47.880 --> 00:18:50.680
<v Speaker 2>acts as a reference pointer. It tells theshall, don't create

397
00:18:50.680 --> 00:18:53.640
<v Speaker 2>a new file named one. Instead, point hose two to

398
00:18:53.720 --> 00:18:55.559
<v Speaker 2>wherever hose one is currently aimed.

399
00:18:55.759 --> 00:18:58.920
<v Speaker 1>Oh, you're bundling the two hoses together into the same bucket.

400
00:18:59.039 --> 00:18:59.400
<v Speaker 2>Exact.

401
00:18:59.440 --> 00:19:01.519
<v Speaker 1>That makes so much much sense visually. Yeah. Now, if

402
00:19:01.519 --> 00:19:04.480
<v Speaker 1>we can seamlessly funnel output into a bucket, the next

403
00:19:04.480 --> 00:19:07.039
<v Speaker 1>logical leap is what if we funnel it straight into

404
00:19:07.039 --> 00:19:10.279
<v Speaker 1>another program? Oh? Yes, This is the digital plumbing of Bash.

405
00:19:10.640 --> 00:19:13.759
<v Speaker 2>The pipe, the pipe symbol. It's that vertical bar on

406
00:19:13.759 --> 00:19:16.720
<v Speaker 2>your keyboard, usually above the ender key. It is arguably

407
00:19:16.759 --> 00:19:19.400
<v Speaker 2>one of the most powerful concepts in all of computing.

408
00:19:19.799 --> 00:19:21.759
<v Speaker 2>It takes the standard output of the program on the

409
00:19:21.839 --> 00:19:24.519
<v Speaker 2>left and funnels it directly into the standard input of

410
00:19:24.519 --> 00:19:25.400
<v Speaker 2>the program on the right.

411
00:19:25.720 --> 00:19:28.960
<v Speaker 1>It's exactly like an assembly line conveyor belt. You have

412
00:19:29.039 --> 00:19:32.920
<v Speaker 1>one small machine that just finds files. It plops them

413
00:19:32.920 --> 00:19:35.400
<v Speaker 1>on the belt. The belt feeds them directly into a

414
00:19:35.400 --> 00:19:39.200
<v Speaker 1>machine that sorts them alphabetically. Right, that machine drops them

415
00:19:39.240 --> 00:19:41.880
<v Speaker 1>on a belt feeding into a machine that removes duplicates.

416
00:19:42.279 --> 00:19:46.440
<v Speaker 1>You're building a custom complex factory out of simple single

417
00:19:46.480 --> 00:19:47.240
<v Speaker 1>purpose tools.

418
00:19:47.599 --> 00:19:51.559
<v Speaker 2>M Because it's a pipe, it's actually performing rudimentary parallel processing.

419
00:19:52.039 --> 00:19:54.599
<v Speaker 2>The second program doesn't read for the first program to

420
00:19:54.599 --> 00:19:57.440
<v Speaker 2>finish completely. As soon as the first program produces a

421
00:19:57.480 --> 00:20:00.240
<v Speaker 2>single drop of data, it flows down the pie to

422
00:20:00.279 --> 00:20:01.000
<v Speaker 2>the next program.

423
00:20:01.200 --> 00:20:03.759
<v Speaker 1>But what if I'm building this complex pipeline and I

424
00:20:03.839 --> 00:20:06.000
<v Speaker 1>want to save a copy of the data halfway down

425
00:20:06.000 --> 00:20:08.799
<v Speaker 1>the assembly line without stopping the belt, Like I want

426
00:20:08.839 --> 00:20:11.519
<v Speaker 1>to sort the data, save a copy to check my work,

427
00:20:11.799 --> 00:20:13.480
<v Speaker 1>and then pass it to the duplicate remover.

428
00:20:13.680 --> 00:20:16.319
<v Speaker 2>Then you use a tool literally named after physical plumbing,

429
00:20:16.440 --> 00:20:20.279
<v Speaker 2>the T command tee. It acts exactly like a T

430
00:20:20.480 --> 00:20:22.799
<v Speaker 2>joint under your sink. You place it in your pipeline

431
00:20:22.839 --> 00:20:27.200
<v Speaker 2>for example, sort pipetcheck dot txt pipe unique. The T

432
00:20:27.359 --> 00:20:30.759
<v Speaker 2>command takes the flowing data, pours a copy into check

433
00:20:30.839 --> 00:20:34.759
<v Speaker 2>dot txt, and simultaneously lets the original stream continue down

434
00:20:34.799 --> 00:20:36.960
<v Speaker 2>the pipe so the next program can consume it.

435
00:20:36.960 --> 00:20:40.200
<v Speaker 1>It's perfect for debugging a long chain of commands. But

436
00:20:40.759 --> 00:20:42.759
<v Speaker 1>and there is a catch with pipes, right, Pipes only

437
00:20:42.759 --> 00:20:45.359
<v Speaker 1>pass data into a program standard input.

438
00:20:45.559 --> 00:20:46.839
<v Speaker 2>That's true, and some.

439
00:20:46.759 --> 00:20:49.960
<v Speaker 1>Programs stubbornly refuse to listen to standard input. They only

440
00:20:49.960 --> 00:20:52.720
<v Speaker 1>take arguments provide it directly on the command line the

441
00:20:52.839 --> 00:20:55.559
<v Speaker 1>ROM command. The remove command is a classic example. I

442
00:20:55.599 --> 00:20:57.799
<v Speaker 1>can't pipe a list of files into ARM, So how

443
00:20:57.799 --> 00:21:01.160
<v Speaker 1>do I use the output of a search command to deles.

444
00:21:00.799 --> 00:21:03.559
<v Speaker 2>Use command substitution instead of a pipe. You wrap your

445
00:21:03.559 --> 00:21:05.920
<v Speaker 2>search command in a dollar sign and parentheses like this

446
00:21:06.079 --> 00:21:10.119
<v Speaker 2>dot rm dollar sign open parenthesis, fine dot dash name

447
00:21:10.279 --> 00:21:13.279
<v Speaker 2>asterisk dot beck close parenthesis.

448
00:21:13.519 --> 00:21:16.960
<v Speaker 1>So dollar sign open parenthesis, the fine command close parenthesis.

449
00:21:16.960 --> 00:21:18.319
<v Speaker 1>How's that different from a pipe?

450
00:21:18.519 --> 00:21:21.920
<v Speaker 2>The shell sees that dollar sign parenthesis syntax, and it

451
00:21:22.000 --> 00:21:24.640
<v Speaker 2>essentially presses pause on your main command. It opens a

452
00:21:24.640 --> 00:21:28.359
<v Speaker 2>completely separate subshell runs the inner fine command, gathers all

453
00:21:28.359 --> 00:21:31.240
<v Speaker 2>the texts that command spits out, and literally paste that

454
00:21:31.319 --> 00:21:34.400
<v Speaker 2>text back onto the command line right after the ARM wow.

455
00:21:34.440 --> 00:21:37.440
<v Speaker 2>It substitutes the command with its own output, and then

456
00:21:37.480 --> 00:21:39.240
<v Speaker 2>presses play on the main ARM command.

457
00:21:39.440 --> 00:21:43.880
<v Speaker 1>That sounds incredibly powerful, but also incredibly dangerous.

458
00:21:44.039 --> 00:21:48.039
<v Speaker 2>Oh, it is the definition of dangerous. RAM is unforgiving.

459
00:21:48.200 --> 00:21:50.720
<v Speaker 2>There is no recycle bin on the command line. Right

460
00:21:51.000 --> 00:21:53.359
<v Speaker 2>if you make a typo in that inner fine command

461
00:21:53.599 --> 00:21:56.759
<v Speaker 2>and it locates more files than you intended. Say it

462
00:21:56.839 --> 00:22:00.519
<v Speaker 2>accidentally lists every file in your home directory. The subshell

463
00:22:00.559 --> 00:22:02.799
<v Speaker 2>will paste all of those file names directly into the

464
00:22:02.880 --> 00:22:05.599
<v Speaker 2>arm command and they are gone forever ouch.

465
00:22:05.920 --> 00:22:08.920
<v Speaker 1>So the rule is always test the inner command first.

466
00:22:08.960 --> 00:22:12.319
<v Speaker 1>Always run the fine command by itself. Verify the list

467
00:22:12.319 --> 00:22:14.559
<v Speaker 1>of files on your screen. If it is exactly what

468
00:22:14.640 --> 00:22:16.200
<v Speaker 1>you want to delete, then you can wrap it in

469
00:22:16.240 --> 00:22:18.440
<v Speaker 1>the dollar sign in parentheses and hand it to RAM.

470
00:22:18.920 --> 00:22:20.079
<v Speaker 2>Precision is everything.

471
00:22:20.400 --> 00:22:24.119
<v Speaker 1>Okay, so we've mastered building megaphones. We can pipe data out,

472
00:22:24.359 --> 00:22:27.799
<v Speaker 1>redirect it, and substitute it. Let's pivot. What if a

473
00:22:27.799 --> 00:22:30.839
<v Speaker 1>program needs us to feed it raw materials? First, how

474
00:22:30.880 --> 00:22:33.559
<v Speaker 1>do we force feed data into a system. Because this

475
00:22:33.599 --> 00:22:36.720
<v Speaker 1>is where shell scripts evolve from static lists of commands

476
00:22:37.079 --> 00:22:38.880
<v Speaker 1>into truly interactive tools.

477
00:22:39.039 --> 00:22:41.799
<v Speaker 2>Well, if output redirection uses the greater than signed to

478
00:22:41.839 --> 00:22:45.119
<v Speaker 2>push data out, input redirection uses the less then signed

479
00:22:45.160 --> 00:22:47.359
<v Speaker 2>to pull data in, it points the other way, right.

480
00:22:47.519 --> 00:22:50.240
<v Speaker 2>If a program expects you to manually type data on

481
00:22:50.279 --> 00:22:53.519
<v Speaker 2>the keyboard, you can just use less than data dot

482
00:22:53.559 --> 00:22:57.160
<v Speaker 2>txt to pour the contents of that file directly into

483
00:22:57.200 --> 00:22:58.160
<v Speaker 2>the program's input.

484
00:22:58.440 --> 00:23:00.359
<v Speaker 1>But what if I am writing a script to share

485
00:23:00.400 --> 00:23:02.400
<v Speaker 1>with my team, and I don't want to email them

486
00:23:02.440 --> 00:23:04.559
<v Speaker 1>the script file on a separate data file. I want

487
00:23:04.559 --> 00:23:07.119
<v Speaker 1>the data hard coded right inside the script itself.

488
00:23:07.160 --> 00:23:09.720
<v Speaker 2>You use what's called a here document. The syntax is

489
00:23:09.720 --> 00:23:12.599
<v Speaker 2>two less than signs followed by a marker word. Traditionally,

490
00:23:12.640 --> 00:23:15.160
<v Speaker 2>programmers use eof, which stands for end of file.

491
00:23:15.400 --> 00:23:19.200
<v Speaker 1>Wait, how does less than less than eof work? Conceptually?

492
00:23:19.559 --> 00:23:22.200
<v Speaker 2>Normally, a script asks for a file on your hard

493
00:23:22.279 --> 00:23:25.039
<v Speaker 2>drive to get data. The double less then tells the

494
00:23:25.079 --> 00:23:28.279
<v Speaker 2>shell don't go looking on the hard drive. The file

495
00:23:28.359 --> 00:23:30.720
<v Speaker 2>is right here glued to the bottom of this script.

496
00:23:31.400 --> 00:23:33.720
<v Speaker 2>Keep reading the following lines and treat them as raw

497
00:23:33.799 --> 00:23:37.119
<v Speaker 2>data until you hit this exact password eof on a

498
00:23:37.200 --> 00:23:38.279
<v Speaker 2>line by itself.

499
00:23:38.440 --> 00:23:42.359
<v Speaker 1>It's like an inline data stream. But the cookbook mentions

500
00:23:42.440 --> 00:23:45.000
<v Speaker 1>a bizarre bug that happens with here documents.

501
00:23:45.079 --> 00:23:46.319
<v Speaker 2>Oh, the dollar sign issue.

502
00:23:46.400 --> 00:23:49.279
<v Speaker 1>Yeah. Let's say I write a script to log charitable donations.

503
00:23:49.279 --> 00:23:51.920
<v Speaker 1>I use a here document to store the data. PETE

504
00:23:51.920 --> 00:23:54.759
<v Speaker 1>gave one hundred dollars with a dollar sign. But when

505
00:23:54.799 --> 00:23:58.119
<v Speaker 1>I run the script, it prints out PETE gave zero zero.

506
00:23:58.640 --> 00:23:59.680
<v Speaker 1>What did one hundred bucks go?

507
00:24:00.119 --> 00:24:02.519
<v Speaker 2>We are back to the aggressive listener and the tyranny

508
00:24:02.599 --> 00:24:05.400
<v Speaker 2>of the dollar sign Even inside a here document, the

509
00:24:05.480 --> 00:24:08.400
<v Speaker 2>shell is still scanning your text. No, it sees dollar

510
00:24:08.440 --> 00:24:11.279
<v Speaker 2>sign one hundred. It assumes dollar sign one is a

511
00:24:11.359 --> 00:24:14.079
<v Speaker 2>variable you are trying to call. That variable is empty,

512
00:24:14.240 --> 00:24:16.559
<v Speaker 2>so it deletes the dollar sign one, leaving just the

513
00:24:16.640 --> 00:24:17.200
<v Speaker 2>zero zero.

514
00:24:17.240 --> 00:24:19.440
<v Speaker 1>So how do we stop it from scanning the data.

515
00:24:19.599 --> 00:24:22.519
<v Speaker 2>We go back to our quoting rules. If you put

516
00:24:22.799 --> 00:24:27.079
<v Speaker 2>single quotes around your marker word typing less than quote

517
00:24:27.119 --> 00:24:32.200
<v Speaker 2>eof quote, you are essentially locking the entire here document

518
00:24:32.319 --> 00:24:35.640
<v Speaker 2>in that steelbox. You're telling the shell turn off all

519
00:24:35.680 --> 00:24:39.079
<v Speaker 2>special features. Do not expand variables. Just read this data

520
00:24:39.119 --> 00:24:42.680
<v Speaker 2>exactly is written. Your one hundred dollars remains one hundred dollars.

521
00:24:43.039 --> 00:24:47.279
<v Speaker 1>That is a subtle fix, but incredibly powerful. Though the

522
00:24:47.319 --> 00:24:50.880
<v Speaker 1>cookbook also notes the eof marker itself is incredibly.

523
00:24:50.400 --> 00:24:54.079
<v Speaker 2>Fragile, extremely fragile. The ending marker must be pristine. If

524
00:24:54.119 --> 00:24:57.480
<v Speaker 2>you have even a single trailing blank space after the

525
00:24:57.480 --> 00:24:59.880
<v Speaker 2>word eof at the end of your data, Bash will

526
00:25:00.200 --> 00:25:00.880
<v Speaker 2>recognize it.

527
00:25:00.880 --> 00:25:01.680
<v Speaker 1>It'll just keep going.

528
00:25:01.839 --> 00:25:03.759
<v Speaker 2>Yes, it will think the data is still going. It

529
00:25:03.799 --> 00:25:06.000
<v Speaker 2>will swallow the rest of your script, treating your actual

530
00:25:06.039 --> 00:25:09.279
<v Speaker 2>commands as text data, and the whole thing will silently.

531
00:25:08.880 --> 00:25:11.039
<v Speaker 1>Break No trailing space is allowed. Got it?

532
00:25:11.440 --> 00:25:13.119
<v Speaker 2>Now? What if we don't want a hard code data.

533
00:25:13.640 --> 00:25:15.880
<v Speaker 2>What if we want our script to actually pause and

534
00:25:16.039 --> 00:25:18.039
<v Speaker 2>ask the human a question in real time?

535
00:25:18.359 --> 00:25:20.440
<v Speaker 1>That is the job of the read command. It grabs

536
00:25:20.440 --> 00:25:22.839
<v Speaker 1>input directly from the keyboard and stores it in a variable,

537
00:25:23.079 --> 00:25:26.119
<v Speaker 1>and it has some fantastic flags for usability.

538
00:25:25.720 --> 00:25:28.319
<v Speaker 2>Like what You can use read dash P to provide

539
00:25:28.319 --> 00:25:31.759
<v Speaker 2>a custom prompt like read dash P enter your name.

540
00:25:32.319 --> 00:25:35.319
<v Speaker 1>And my absolute favorite feature is read dash T, which

541
00:25:35.319 --> 00:25:37.319
<v Speaker 1>sets a time limit. Yes, you could do read dash

542
00:25:37.319 --> 00:25:40.000
<v Speaker 1>T three dash pe answer quickly. If the user doesn't

543
00:25:40.039 --> 00:25:43.160
<v Speaker 1>type anything within three seconds, the read command times out

544
00:25:43.279 --> 00:25:45.400
<v Speaker 1>and the script just moves on to the next line.

545
00:25:45.440 --> 00:25:49.000
<v Speaker 2>It's brilliant for automation. It allows you to write scripts

546
00:25:49.039 --> 00:25:52.200
<v Speaker 2>that run on their own with default behaviors, but still

547
00:25:52.240 --> 00:25:54.359
<v Speaker 2>give you a three second window to interrupt them if

548
00:25:54.400 --> 00:25:57.079
<v Speaker 2>you happen to be watching the screen. It's the mark

549
00:25:57.160 --> 00:25:58.839
<v Speaker 2>of a truly professional script.

550
00:25:59.079 --> 00:26:02.640
<v Speaker 1>So we started this deep dive looking at a blinking cursor,

551
00:26:03.000 --> 00:26:07.160
<v Speaker 1>feeling completely intimidated by its aggressive, literal nature. But now

552
00:26:07.160 --> 00:26:09.440
<v Speaker 1>we see it for what it is. The command line

553
00:26:09.480 --> 00:26:12.519
<v Speaker 1>isn't a nostalgic textbox. It is the connective tissue of

554
00:26:12.559 --> 00:26:13.359
<v Speaker 1>the operating system.

555
00:26:13.519 --> 00:26:14.160
<v Speaker 2>It really is.

556
00:26:14.319 --> 00:26:17.880
<v Speaker 1>By understanding the rules of quoting, knowing how filed descriptors

557
00:26:17.920 --> 00:26:21.119
<v Speaker 1>route your data, and mastering the plumbing of pipes and redirects,

558
00:26:21.400 --> 00:26:24.079
<v Speaker 1>you stop just using your computer and you start commanding it.

559
00:26:24.200 --> 00:26:26.880
<v Speaker 2>And that is the true joy of Bash. It rewards

560
00:26:26.920 --> 00:26:30.000
<v Speaker 2>precision and it vastly amplifies your creative.

561
00:26:29.839 --> 00:26:31.880
<v Speaker 1>So we'll leave you with a challenge. Think about your

562
00:26:31.960 --> 00:26:34.720
<v Speaker 1>daily digital life. The command line is basically just a

563
00:26:34.799 --> 00:26:40.039
<v Speaker 1>highly efficient conversation using tiny, modular verbs. What complex, repetitive

564
00:26:40.079 --> 00:26:44.519
<v Speaker 1>task do you do every single week? Resizing images, organizing downloads,

565
00:26:44.720 --> 00:26:47.480
<v Speaker 1>searching for errors and logs that could be completely automated

566
00:26:47.519 --> 00:26:49.960
<v Speaker 1>with just three or four words piped together. The cursor

567
00:26:50.160 --> 00:26:52.440
<v Speaker 1>is blinking. It's waiting for you to start the conversation.
