changeset 46:89fdc29b296f

learn_bash work
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 05 Jan 2024 20:58:57 -0700
parents 14518d772090
children 84dd3edd03e9
files src/learn_bash.html.luan src/site.css
diffstat 2 files changed, 393 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/learn_bash.html.luan	Fri Jan 05 01:34:32 2024 -0700
+++ b/src/learn_bash.html.luan	Fri Jan 05 20:58:57 2024 -0700
@@ -13,7 +13,7 @@
 		title = [[Introduction]]
 		content = function()
 %>
-<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>
+<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>
 
 <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>
 <%
@@ -136,6 +136,393 @@
 <%
 		end
 	}
+	dirs = {
+		title = [[Directories]]
+		content = function()
+%>
+<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>
+
+<p>On Mac:</p>
+
+<code block>
+~ $ pwd
+/Users/fschmidt
+~ $ open .
+~ $ 
+</code>
+
+<p>On Windows:</p>
+
+<code block>
+~ $ pwd
+/home/fschmidt
+~ $ explorer .
+~ $
+</code>
+
+<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>
+
+<p>Continuing on my Mac:</p>
+
+<code block>
+~ $ mkdir learn
+~ $ cd learn
+~/learn $ pwd
+/Users/fschmidt/learn
+</code>
+
+<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>
+
+<code block>
+~/learn $ pwd
+/Users/fschmidt/learn
+~/learn $ ls
+~/learn $ touch file1
+~/learn $ ls
+file1
+~/learn $ touch file2
+~/learn $ touch file3
+~/learn $ ls
+file1	file2	file3
+~/learn $ mkdir dir1
+~/learn $ ls
+dir1	file1	file2	file3
+~/learn $ ls -F
+dir1/	file1	file2	file3
+~/learn $ ls -a
+.	..	dir1	file1	file2	file3
+~/learn $ ls -a -F
+./	../	dir1/	file1	file2	file3
+~/learn $ ls -aF
+./	../	dir1/	file1	file2	file3
+</code>
+
+<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>
+
+<code block>
+~/learn $ ls file1
+file1
+~/learn $ ls qqq
+ls: qqq: No such file or directory
+~/learn $ ls file1 qqq file2
+ls: qqq: No such file or directory
+file1	file2
+~/learn $ ls dir1
+~/learn $ touch dir1/d1file
+~/learn $ ls dir1
+d1file
+~/learn $ ls -d dir1
+dir1
+~/learn $ ls file1 file2 dir1
+file1	file2
+
+dir1:
+d1file
+~/learn $ ls -d file1 file2 dir1
+dir1	file1	file2
+~/learn $ ls -dF file1 file2 dir1
+dir1/	file1	file2
+</code>
+
+<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>
+
+<code block>
+~/learn $ ls
+dir1	file1	file2	file3
+~/learn $ ls .
+dir1	file1	file2	file3
+~/learn $ ls -d .
+.
+~/learn $ ls -dF .
+./
+~/learn $ ls ./file1
+./file1
+~/learn $ ls dir1
+d1file
+~/learn $ ls ./dir1
+d1file
+~/learn $ pwd
+/Users/fschmidt/learn
+~/learn $ cd .
+~/learn $ pwd
+/Users/fschmidt/learn
+</code>
+
+<p><code>.</code> is the current directory.</p>
+
+<code block>
+~/learn $ pwd
+/Users/fschmidt/learn
+~/learn $ cd dir1
+~/learn/dir1 $ pwd
+/Users/fschmidt/learn/dir1
+~/learn/dir1 $ ls .
+d1file
+~/learn/dir1 $ ls ..
+dir1	file1	file2	file3
+~/learn/dir1 $ cd ..
+~/learn $ pwd
+/Users/fschmidt/learn
+~/learn $ cd dir1
+~/learn/dir1 $ pwd
+/Users/fschmidt/learn/dir1
+~/learn/dir1 $ cd ../..
+~ $ pwd
+/Users/fschmidt
+~ $ cd learn
+~/learn $ pwd
+/Users/fschmidt/learn
+</code>
+
+<p><code>..</code> is the parent directory.</p>
+
+<code block>
+~/learn $ echo *
+dir1 file1 file2 file3
+~/learn $ echo d*
+dir1
+~/learn $ echo f*
+file1 file2 file3
+~/learn $ echo *1
+dir1 file1
+~/learn $ echo dir1/*
+dir1/d1file
+~/learn $ echo */*
+dir1/d1file
+~/learn $ echo qqq*
+qqq*
+</code>
+
+<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>
+
+<code block>
+~/learn $ ls *
+file1	file2	file3
+
+dir1:
+d1file
+~/learn $ ls -dF *
+dir1/	file1	file2	file3
+~/learn $ ls -dF d*
+dir1/
+~/learn $ ls -dF f*
+file1	file2	file3
+~/learn $ ls -dF *1
+dir1/	file1
+~/learn $ ls dir1/*
+dir1/d1file
+~/learn $ ls */*
+dir1/d1file
+~/learn $ ls -dF qqq*
+ls: qqq*: No such file or directory
+</code>
+
+<p>Should be self-explanatory.</p>
+
+<code block>
+~/learn $ pwd
+/Users/fschmidt/learn
+~/learn $ cd ~
+~ $ pwd
+/Users/fschmidt
+~ $ cd learn/dir1
+~/learn/dir1 $ pwd
+/Users/fschmidt/learn/dir1
+~/learn/dir1 $ cd
+~ $ pwd
+/Users/fschmidt
+~ $  cd ~/learn
+~/learn $ pwd
+/Users/fschmidt/learn
+~/learn $ echo ~
+/Users/fschmidt
+~/learn $ echo .
+.
+~/learn $ echo ..
+..
+</code>
+
+<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>
+
+<code block>
+~/learn $ ls -ltF
+total 0
+drwxr-xr-x  3 fschmidt  staff  96 Jan  5 02:33 dir1/
+-rw-r--r--  1 fschmidt  staff   0 Jan  5 02:21 file3
+-rw-r--r--  1 fschmidt  staff   0 Jan  5 02:21 file2
+-rw-r--r--  1 fschmidt  staff   0 Jan  5 02:21 file1
+</code>
+
+<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>
+
+<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>
+
+<code block>
+~/learn $ echo file
+file1  file2  file3  
+~/learn $ echo file
+</code>
+
+<p>In general, you can press tab anytime while entering a file name and see what happens.  Autocompletion saves a lot of typing.</p>
+<%
+		end
+	}
+	files = {
+		title = [[Working with Files]]
+		content = function()
+%>
+<p></p>
+<code block>
+~/learn $ ls -F
+dir1/	file1	file2	file3
+~/learn $ cp file1 copied
+~/learn $ ls -F
+copied	dir1/	file1	file2	file3
+~/learn $ mv copied moved
+~/learn $ ls -F
+dir1/	file1	file2	file3	moved
+~/learn $ rm moved
+~/learn $ ls -F
+dir1/	file1	file2	file3
+</code>
+
+<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>
+
+<code block>
+~/learn $ ls -F
+dir1/	file1	file2	file3
+~/learn $ mkdir dir2
+~/learn $ touch dir2/d2file
+~/learn $ ls -F
+dir1/	dir2/	file1	file2	file3
+~/learn $ ls dir2
+d2file
+~/learn $ rm dir2
+rm: dir2: is a directory
+~/learn $ rm -d dir2
+rm: dir2: Directory not empty
+~/learn $ rm dir2/d2file 
+~/learn $ rm -d dir2
+~/learn $ ls -F
+dir1/	file1	file2	file3
+</code>
+
+<p></p>
+
+<code block>
+~/learn $ ls -F
+dir1/	file1	file2	file3
+~/learn $ mkdir dir2
+~/learn $ touch dir2/d2file
+~/learn $ ls -F
+dir1/	dir2/	file1	file2	file3
+~/learn $ rm -R dir2
+~/learn $ ls -F
+dir1/	file1	file2	file3
+</code>
+
+<p></p>
+
+<code block>
+~/learn $ ls -F
+dir1/	file1	file2	file3
+~/learn $ cp dir1 dir2
+cp: dir1 is a directory (not copied).
+~/learn $ cp -R dir1 dir2
+~/learn $ ls -F
+dir1/	dir2/	file1	file2	file3
+~/learn $ ls dir2
+d1file
+~/learn $ cp f* dir2
+~/learn $ ls dir2
+d1file	file1	file2	file3
+~/learn $ rm -R dir2
+~/learn $ ls -F
+dir1/	file1	file2	file3
+</code>
+
+<p></p>
+
+<code block>
+~/learn $ ls -F
+dir1/	file1	file2	file3
+~/learn $ mkdir dir2
+~/learn $ cp -R dir1 dir2
+~/learn $ ls -F dir2
+dir1/
+~/learn $ ls -F dir2/dir1
+d1file
+~/learn $ rm -R dir2
+~/learn $ ls -F
+dir1/	file1	file2	file3
+</code>
+
+<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>
+<%
+		end
+	}
+	quote = {
+		title = [[Quoting]]
+		content = function()
+%>
+<p></p>
+
+<code block>
+~/learn $ echo a   b
+a b
+~/learn $ echo "a   b"
+a   b
+~/learn $ echo 'a   b'
+a   b
+~/learn $ echo "a   b"   c
+a   b c
+</code>
+
+<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>
+
+<code block>
+~/learn $ echo a\ \ \ b
+a   b
+</code>
+
+<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>
+
+<%
+		end
+	}
+	vars = {
+		title = [[Variables]]
+		content = function()
+%>
+<p></p>
+
+<code block>
+~/learn $ echo $X
+
+~/learn $ X="some text"
+~/learn $ echo $X
+some text
+~/learn $ echo "X is: $X"
+X is: some text
+~/learn $ echo 'X is: $X'
+X is: $X
+~/learn $ X="$X and more"
+~/learn $ echo $X
+some text and more
+</code>
+
+<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>
+<%
+		end
+	}
+	bash_profile = {
+		title = [[.bash_profile]]
+		content = function()
+%>
+<p>later</p>
+<%
+		end
+	}
 	later = {
 		title = [[placeholder]]
 		content = function()
--- a/src/site.css	Fri Jan 05 01:34:32 2024 -0700
+++ b/src/site.css	Fri Jan 05 20:58:57 2024 -0700
@@ -42,17 +42,20 @@
 }
 
 code {
-	background-color: #EEE;
+	background-color: #DDD;
+	white-space: pre;
 	padding: 2px;
 }
 code[block] {
-	white-space: pre;
 	display: block;
 	padding: 1em;
 }
 code[block]:first-line {
 	line-height: 0;
 }
+span[pre] {
+	white-space: pre;
+}
 
 div[toc] ul {
 	list-style-type: none;