Mercurial Hosting > reactionary
diff 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 |
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()