comparison src/learn_bash.html.luan @ 46:89fdc29b296f

learn_bash work
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 05 Jan 2024 20:58:57 -0700
parents 14518d772090
children 84dd3edd03e9
comparison
equal deleted inserted replaced
45:14518d772090 46:89fdc29b296f
11 local content = { 11 local content = {
12 intro = { 12 intro = {
13 title = [[Introduction]] 13 title = [[Introduction]]
14 content = function() 14 content = function()
15 %> 15 %>
16 <p>I really don't want to write this tutorial, but all the existing Bash tutorials are so horrible that I have no choice. I looked at books, websites, and YouTube - all horrible. They don't start with the basics. They include all kinds of useless crap. And they don't explain core concepts. So I have no choice but to write this damn thing.</p> 16 <p>I really don't want to write this tutorial, but all the existing <a href="bash.html">Bash</a> tutorials are so horrible that I have no choice. I looked at books, websites, and YouTube - all horrible. They don't start with the basics. They include all kinds of useless crap. And they don't explain core concepts. So I have no choice but to write this damn thing for my <a href="http://localhost:8080/learn.html#bash">Learn Reactionary Programming</a> Bash lesson.</p>
17 17
18 <p>I will focus on Mac and Windows. I don't have Linux, and I hate Linux, so I won't discuss it. Most of Bash is the same on Mac and Windows, but where they differ, I will discuss both.</p> 18 <p>I will focus on Mac and Windows. I don't have Linux, and I hate Linux, so I won't discuss it. Most of Bash is the same on Mac and Windows, but where they differ, I will discuss both.</p>
19 <% 19 <%
20 end 20 end
21 } 21 }
131 <p>to install <code>man</code> as described <a href="https://packages.msys2.org/package/man-db">here</a> and then try <code>man echo</code> again.</p> 131 <p>to install <code>man</code> as described <a href="https://packages.msys2.org/package/man-db">here</a> and then try <code>man echo</code> again.</p>
132 132
133 <p>The <code>man</code> command shows documentation of commands. Unfortunately it has a silly user interface based on memorizing keys, so I will just tell you the few keys you need. Down-arrow and up-arrow move down and up by one line. The space key moves down by one page. And most importantly, typing "q" quits and takes you back to Bash. You just have to memorize this.</p> 133 <p>The <code>man</code> command shows documentation of commands. Unfortunately it has a silly user interface based on memorizing keys, so I will just tell you the few keys you need. Down-arrow and up-arrow move down and up by one line. The space key moves down by one page. And most importantly, typing "q" quits and takes you back to Bash. You just have to memorize this.</p>
134 134
135 <p>Now try entering <code>man man</code>. You don't need all the stuff shown, but you can see what a complicated man page looks like. You can use <code>man</code> to get the documentation of other commands as I discuss them.</p> 135 <p>Now try entering <code>man man</code>. You don't need all the stuff shown, but you can see what a complicated man page looks like. You can use <code>man</code> to get the documentation of other commands as I discuss them.</p>
136 <%
137 end
138 }
139 dirs = {
140 title = [[Directories]]
141 content = function()
142 %>
143 <p>You should be familiar with Mac Finder or Windows File Explorer, and you should know from this that directories (also called "folders") are organized into a tree.</p>
144
145 <p>On Mac:</p>
146
147 <code block>
148 ~ $ pwd
149 /Users/fschmidt
150 ~ $ open .
151 ~ $
152 </code>
153
154 <p>On Windows:</p>
155
156 <code block>
157 ~ $ pwd
158 /home/fschmidt
159 ~ $ explorer .
160 ~ $
161 </code>
162
163 <p>When using Bash, you are always in some directory, called the current directory or the working directory. <code>pwd</code> shows you the full path to this directory. Do <code>man pwd</code> for details.<p>
164
165 <p>Continuing on my Mac:</p>
166
167 <code block>
168 ~ $ mkdir learn
169 ~ $ cd learn
170 ~/learn $ pwd
171 /Users/fschmidt/learn
172 </code>
173
174 <p><code>mkdir</code> makes a directory in the current directory. You should be able to see the created directory in Mac Finder or Windows File Explorer. <code>cd</code> stands for "change directory". This changes the current directory. <code>cd</code> is a built-in command (built into Bash), and <code>man</code> isn't useful with built-in commands, so instead of <code>man cd</code>, try <code>help cd</code>. Continuing...</p>
175
176 <code block>
177 ~/learn $ pwd
178 /Users/fschmidt/learn
179 ~/learn $ ls
180 ~/learn $ touch file1
181 ~/learn $ ls
182 file1
183 ~/learn $ touch file2
184 ~/learn $ touch file3
185 ~/learn $ ls
186 file1 file2 file3
187 ~/learn $ mkdir dir1
188 ~/learn $ ls
189 dir1 file1 file2 file3
190 ~/learn $ ls -F
191 dir1/ file1 file2 file3
192 ~/learn $ ls -a
193 . .. dir1 file1 file2 file3
194 ~/learn $ ls -a -F
195 ./ ../ dir1/ file1 file2 file3
196 ~/learn $ ls -aF
197 ./ ../ dir1/ file1 file2 file3
198 </code>
199
200 <p><code>ls</code> lists files and <code>touch</code> creates an empty file. Arguments that start with "-" are options. Do <code>man ls</code> to see what the options I used do. <code>-F</code> appends a "/" to directories, and <code>-a</code> shows files starting with "." which are usually hidden. Options can be combined.</p>
201
202 <code block>
203 ~/learn $ ls file1
204 file1
205 ~/learn $ ls qqq
206 ls: qqq: No such file or directory
207 ~/learn $ ls file1 qqq file2
208 ls: qqq: No such file or directory
209 file1 file2
210 ~/learn $ ls dir1
211 ~/learn $ touch dir1/d1file
212 ~/learn $ ls dir1
213 d1file
214 ~/learn $ ls -d dir1
215 dir1
216 ~/learn $ ls file1 file2 dir1
217 file1 file2
218
219 dir1:
220 d1file
221 ~/learn $ ls -d file1 file2 dir1
222 dir1 file1 file2
223 ~/learn $ ls -dF file1 file2 dir1
224 dir1/ file1 file2
225 </code>
226
227 <p>Without file arguments, <code>ls</code> lists files in the current directory. With file arguments, it lists those files if they exist. If the file is a directory, it will list what is in the directory unless the <code>-d</code> option is used.</p>
228
229 <code block>
230 ~/learn $ ls
231 dir1 file1 file2 file3
232 ~/learn $ ls .
233 dir1 file1 file2 file3
234 ~/learn $ ls -d .
235 .
236 ~/learn $ ls -dF .
237 ./
238 ~/learn $ ls ./file1
239 ./file1
240 ~/learn $ ls dir1
241 d1file
242 ~/learn $ ls ./dir1
243 d1file
244 ~/learn $ pwd
245 /Users/fschmidt/learn
246 ~/learn $ cd .
247 ~/learn $ pwd
248 /Users/fschmidt/learn
249 </code>
250
251 <p><code>.</code> is the current directory.</p>
252
253 <code block>
254 ~/learn $ pwd
255 /Users/fschmidt/learn
256 ~/learn $ cd dir1
257 ~/learn/dir1 $ pwd
258 /Users/fschmidt/learn/dir1
259 ~/learn/dir1 $ ls .
260 d1file
261 ~/learn/dir1 $ ls ..
262 dir1 file1 file2 file3
263 ~/learn/dir1 $ cd ..
264 ~/learn $ pwd
265 /Users/fschmidt/learn
266 ~/learn $ cd dir1
267 ~/learn/dir1 $ pwd
268 /Users/fschmidt/learn/dir1
269 ~/learn/dir1 $ cd ../..
270 ~ $ pwd
271 /Users/fschmidt
272 ~ $ cd learn
273 ~/learn $ pwd
274 /Users/fschmidt/learn
275 </code>
276
277 <p><code>..</code> is the parent directory.</p>
278
279 <code block>
280 ~/learn $ echo *
281 dir1 file1 file2 file3
282 ~/learn $ echo d*
283 dir1
284 ~/learn $ echo f*
285 file1 file2 file3
286 ~/learn $ echo *1
287 dir1 file1
288 ~/learn $ echo dir1/*
289 dir1/d1file
290 ~/learn $ echo */*
291 dir1/d1file
292 ~/learn $ echo qqq*
293 qqq*
294 </code>
295
296 <p><code>*</code> does wildcard matching of files. It is important to understand that Bash does the wildcard matching and then passes the resulting arguments to the command. <code>echo</code> never sees the "*" unless there is no match.</p>
297
298 <code block>
299 ~/learn $ ls *
300 file1 file2 file3
301
302 dir1:
303 d1file
304 ~/learn $ ls -dF *
305 dir1/ file1 file2 file3
306 ~/learn $ ls -dF d*
307 dir1/
308 ~/learn $ ls -dF f*
309 file1 file2 file3
310 ~/learn $ ls -dF *1
311 dir1/ file1
312 ~/learn $ ls dir1/*
313 dir1/d1file
314 ~/learn $ ls */*
315 dir1/d1file
316 ~/learn $ ls -dF qqq*
317 ls: qqq*: No such file or directory
318 </code>
319
320 <p>Should be self-explanatory.</p>
321
322 <code block>
323 ~/learn $ pwd
324 /Users/fschmidt/learn
325 ~/learn $ cd ~
326 ~ $ pwd
327 /Users/fschmidt
328 ~ $ cd learn/dir1
329 ~/learn/dir1 $ pwd
330 /Users/fschmidt/learn/dir1
331 ~/learn/dir1 $ cd
332 ~ $ pwd
333 /Users/fschmidt
334 ~ $ cd ~/learn
335 ~/learn $ pwd
336 /Users/fschmidt/learn
337 ~/learn $ echo ~
338 /Users/fschmidt
339 ~/learn $ echo .
340 .
341 ~/learn $ echo ..
342 ..
343 </code>
344
345 <p><code>~</code> means your home directory. <code>cd</code> without arguments is the same as <code>cd ~</code>. <code>~</code> is expanded into your home directory by Bash.</p>
346
347 <code block>
348 ~/learn $ ls -ltF
349 total 0
350 drwxr-xr-x 3 fschmidt staff 96 Jan 5 02:33 dir1/
351 -rw-r--r-- 1 fschmidt staff 0 Jan 5 02:21 file3
352 -rw-r--r-- 1 fschmidt staff 0 Jan 5 02:21 file2
353 -rw-r--r-- 1 fschmidt staff 0 Jan 5 02:21 file1
354 </code>
355
356 <p><code>-l</code> gives you this ugly techy format. You get the date that the file was last modified. Before the date is the file size. <code>-t</code> sorts by date descending.</p>
357
358 <p>Lastly I will describe autocompletion. I type <code>echo d</code> without enter/return but instead then press the tab key. It autocompletes to <code>echo dir1/</code>. I press tab again and it autocompletes to <code>echo dir1/d1file</code>. Pressing tab while entering a file or directory makes Bash try to autocomplete using matching file names. If I enter <code>echo f</code> and press tab, I get <code>echo file</code>. It doesn't know which to choose next. Another tab just beeps. And another tab shows me the options like this:</p>
359
360 <code block>
361 ~/learn $ echo file
362 file1 file2 file3
363 ~/learn $ echo file
364 </code>
365
366 <p>In general, you can press tab anytime while entering a file name and see what happens. Autocompletion saves a lot of typing.</p>
367 <%
368 end
369 }
370 files = {
371 title = [[Working with Files]]
372 content = function()
373 %>
374 <p></p>
375 <code block>
376 ~/learn $ ls -F
377 dir1/ file1 file2 file3
378 ~/learn $ cp file1 copied
379 ~/learn $ ls -F
380 copied dir1/ file1 file2 file3
381 ~/learn $ mv copied moved
382 ~/learn $ ls -F
383 dir1/ file1 file2 file3 moved
384 ~/learn $ rm moved
385 ~/learn $ ls -F
386 dir1/ file1 file2 file3
387 </code>
388
389 <p><code>cp</code> copies files or directories. <code>mv</code> moves files or directories. <code>rm</code> removes files or directories. See the <code>man</code> pages of these commands for details.</p>
390
391 <code block>
392 ~/learn $ ls -F
393 dir1/ file1 file2 file3
394 ~/learn $ mkdir dir2
395 ~/learn $ touch dir2/d2file
396 ~/learn $ ls -F
397 dir1/ dir2/ file1 file2 file3
398 ~/learn $ ls dir2
399 d2file
400 ~/learn $ rm dir2
401 rm: dir2: is a directory
402 ~/learn $ rm -d dir2
403 rm: dir2: Directory not empty
404 ~/learn $ rm dir2/d2file
405 ~/learn $ rm -d dir2
406 ~/learn $ ls -F
407 dir1/ file1 file2 file3
408 </code>
409
410 <p></p>
411
412 <code block>
413 ~/learn $ ls -F
414 dir1/ file1 file2 file3
415 ~/learn $ mkdir dir2
416 ~/learn $ touch dir2/d2file
417 ~/learn $ ls -F
418 dir1/ dir2/ file1 file2 file3
419 ~/learn $ rm -R dir2
420 ~/learn $ ls -F
421 dir1/ file1 file2 file3
422 </code>
423
424 <p></p>
425
426 <code block>
427 ~/learn $ ls -F
428 dir1/ file1 file2 file3
429 ~/learn $ cp dir1 dir2
430 cp: dir1 is a directory (not copied).
431 ~/learn $ cp -R dir1 dir2
432 ~/learn $ ls -F
433 dir1/ dir2/ file1 file2 file3
434 ~/learn $ ls dir2
435 d1file
436 ~/learn $ cp f* dir2
437 ~/learn $ ls dir2
438 d1file file1 file2 file3
439 ~/learn $ rm -R dir2
440 ~/learn $ ls -F
441 dir1/ file1 file2 file3
442 </code>
443
444 <p></p>
445
446 <code block>
447 ~/learn $ ls -F
448 dir1/ file1 file2 file3
449 ~/learn $ mkdir dir2
450 ~/learn $ cp -R dir1 dir2
451 ~/learn $ ls -F dir2
452 dir1/
453 ~/learn $ ls -F dir2/dir1
454 d1file
455 ~/learn $ rm -R dir2
456 ~/learn $ ls -F
457 dir1/ file1 file2 file3
458 </code>
459
460 <p>I could explain all this, but I won't. You should learn to understand commands and their options using <code>man</code> and by playing with them. Don't continue until you completely understand the above.</p>
461 <%
462 end
463 }
464 quote = {
465 title = [[Quoting]]
466 content = function()
467 %>
468 <p></p>
469
470 <code block>
471 ~/learn $ echo a b
472 a b
473 ~/learn $ echo "a b"
474 a b
475 ~/learn $ echo 'a b'
476 a b
477 ~/learn $ echo "a b" c
478 a b c
479 </code>
480
481 <p>Bash treats text in quotes as one argument. So in <code>echo a b</code>, <code>echo</code> has two arguments: "a" and "b". In <code>echo "a b"</code>, <code>echo</code> has one argument: "<span pre>a b</span>". In <code>echo 'a b'</code>, <code>echo</code> has one argument: "<span pre>a b</span>". In <code>echo "a b" c</code>, <code>echo</code> has two arguments: "<span pre>a b</span>" and "c".</p>
482
483 <code block>
484 ~/learn $ echo a\ \ \ b
485 a b
486 </code>
487
488 <p>Outside of quotes, <code>\ </code> is not treated as a separator, but rather is treated as a space character that is part of the argument.</p>
489
490 <%
491 end
492 }
493 vars = {
494 title = [[Variables]]
495 content = function()
496 %>
497 <p></p>
498
499 <code block>
500 ~/learn $ echo $X
501
502 ~/learn $ X="some text"
503 ~/learn $ echo $X
504 some text
505 ~/learn $ echo "X is: $X"
506 X is: some text
507 ~/learn $ echo 'X is: $X'
508 X is: $X
509 ~/learn $ X="$X and more"
510 ~/learn $ echo $X
511 some text and more
512 </code>
513
514 <p>Here <code>X</code> is a variable. You get its value with <code>$X</code>. This also works inside double-quotes but not inside single-quotes.</p>
515 <%
516 end
517 }
518 bash_profile = {
519 title = [[.bash_profile]]
520 content = function()
521 %>
522 <p>later</p>
136 <% 523 <%
137 end 524 end
138 } 525 }
139 later = { 526 later = {
140 title = [[placeholder]] 527 title = [[placeholder]]