Skip to content

Commit

Permalink
Merge branch 'gh-pages' of github.com:lhunath/guide.bash.academy into…
Browse files Browse the repository at this point in the history
… gh-pages
  • Loading branch information
lhunath committed Apr 24, 2018
2 parents 9eff0ca + d01d66f commit fac02c7
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 28 deletions.
13 changes: 7 additions & 6 deletions _layouts/chapter.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@
{{ content }}

<aside class="nav">
{% assign nextPage = false %}
{% for sitePage in site.pages %}
{% if nextPage %}
<a href="{{ sitePage.url }}">Next up: {{ sitePage.title }}</a>
{% assign found = false %}
{% assign chapters = site.pages | where: 'layout', 'chapter' | sort: 'chapter' %}
{% for chapter in chapters %}
{% if found %}
<a href="{{ chapter.url }}">Next up: {{ chapter.title }}</a>
{% break %}
{% endif %}

{% if sitePage.layout == 'chapter' and sitePage == page %}
{% assign nextPage = true %}
{% if chapter == page %}
{% assign found = true %}
{% endif %}
{% endfor %}
</aside>
9 changes: 4 additions & 5 deletions _layouts/page.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ <h1>Chapters</h1>
<ul>
<li><a href="/">{{ site.title }}<br>
<sub>Back to the front page.</sub></a></li>
{% for page in site.pages %}
{% if page.layout == 'chapter' %}
<li><a href="{{ page.url }}#">{{ page.title }}<br>
<sub>{{ page.subtitle }}</sub></a></li>
{% endif %}
{% assign chapters = site.pages | where: 'layout', 'chapter' | sort: 'chapter' %}
{% for chapter in chapters %}
<li><a href="{{ chapter.url }}#">{{ chapter.title }}<br>
<sub>{{ chapter.subtitle }}</sub></a></li>
{% endfor %}
</ul>
</nav>
Expand Down
2 changes: 1 addition & 1 deletion attributions.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ <h1>Attributions</h1>

<p>Thanks to these great artists for providing their works under permissive licenses so that other artists like I can build on their shoulders and do great things in turn:</p>
<dl>
<dt><img src="img/hard-drive.svg"></dt>
<dt><img src="/img/hard-drive.svg"></dt>
<dd><a href="://thenounproject.com/term/hard-drive/38070/">thenounproject.com/term/hard-drive/38070/</a>
</dl>
17 changes: 10 additions & 7 deletions commands.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
layout: chapter
chapter: 2
title: Commands And Arguments
subtitle: "How do I give bash instructions?"
subtitle: How do I give bash instructions?
status: beta
description: "About what a command is, and how to issue them; interactive mode and scripts; command syntax, searching commands and programs by name; arguments and word splitting as well as input and output redirection."
description: >-
About what a command is, and how to issue them; interactive mode and scripts;
command syntax, searching commands and programs by name; arguments and word
splitting as well as input and output redirection.
published: true
---

Expand Down Expand Up @@ -150,10 +153,10 @@ <h2>About intentions and ambiguity</h2>
do. When <q>Bring the animals book</q> doesn't yet cut it, we need to teach them the steps: <q>Look around, do you see the books behind you?</q>, <q>Great! Can you find the book with the lion and the cow on it?</q>, <q>That's the one, grab it for me!</q>, <q>Good boy, now bring it to daddy! Come here, you.</q>, <q>Hi! Look at you. Give me the book and sit down, let's read it together.</q>; in a way, writing a bash script is similar to teaching your system how to do a task.
The difference is your three year old will recognize previous experiences in new requests by himself, your system won't: you'll need to explicitly specify and run previously written job descriptions.</p>

<p>Some language interpretors (an interpretor is a program, like bash, that can understand a language) try to compensate for this problem by being extremely strict with their grammar and syntax. The idea is to weed out the ambiguity in your language so as to avoid accidentally doing the wrong thing. The interpretor enforces correctness to a certain degree: this tends to be a relatively successful strategy and generally results in the least buggy programs.</p>
<p>Some language interpreters (an interpreter is a program, like bash, that can understand a language) try to compensate for this problem by being extremely strict with their grammar and syntax. The idea is to weed out the ambiguity in your language so as to avoid accidentally doing the wrong thing. The interpreter enforces correctness to a certain degree: this tends to be a relatively successful strategy and generally results in the least buggy programs.</p>

<p>Sadly, bash is not a strict interpretor.<br>
In fact, bash's latitude is largely at fault for the general ineptitude toward bash scripting with most anyone introduced to the language, novice and professional alike. The result is not dissimilar to the state of the web around the turn of the century: Many pages were written so badly that their ability to render properly on any kind of standards-compliant browser was sufficiently compromised to force these browsers to implement all sorts of "smart" hacks in an attempt
<p>Sadly, bash is not a strict interpreter.<br>
In fact, bash's latitude is largely at fault for the general ineptitude toward bash scripting with most anyone introduced to the language, novice and professional alike. The result is not dissimilar to the state of the web around the turn of the century: many pages were written so badly that their ability to render properly on any kind of standards-compliant browser was sufficiently compromised to force these browsers to implement all sorts of "smart" hacks in an attempt
to render the pages as they might have been intended to render, rather than what they were written to render. Similarly, the gross part of the scripts you are going to run into <em>will be buggy</em>. Sometimes subtly so, often to the point where simply using it with a file whose name is somewhat unexpected may cause irreversible damage to your system.</p>
<p><strong>Don't be that person.</strong><br>
This guide exists to teach you to write good bash code. It will empower you to convey your true intentions and have a computer solve your problems. Since bash is a lax interpreter, <em>the responsibility of discipline lays with you</em>. If you're not up to honoring this prerequisite, I recommend you stop reading now and find a strict interpreter instead. There is too much bad bash code in the world, and this guide will not be responsible for empowering people to write
Expand Down Expand Up @@ -186,7 +189,7 @@ <h2>The basic grammar of a bash command</h2>
<pre>
<samp>This is what <u title="And this is an annotation in the example.">an example</u> looks like.</samp>
<samp>And this is a second example of an example.</samp></pre></p>
<p>In the syntax block, we use angular brackets (<code>[ ]</code>) around parts of the syntax that are optional. You'll notice the first code example doesn't contain a <code><var>var</var><strong>=</strong><var>value</var></code> part but the second example does. This part of the syntax is available to you if you need it, but can be omitted if you don't.
<p>In the syntax block, we use square brackets (<code>[ ]</code>) around parts of the syntax that are optional. You'll notice the first code example doesn't contain a <code><var>var</var><strong>=</strong><var>value</var></code> part but the second example does. This part of the syntax is available to you if you need it, but can be omitted if you don't.
Finally, when an element of the syntax can be repeated as many times as you might need it, we indicate this with three dots (<code>...</code>). For instance, the above syntax allows you to optionally specify as many <var>redirection</var>s as you might need.</p></aside>

<p>Before the command's name you can <em>optionally</em> put a few <var>var</var> assignments. These variable assignments apply to the environment of this one command only. We'll go more in depth on variables and environment later on.</p>
Expand Down Expand Up @@ -270,7 +273,7 @@ <h2>The basic grammar of a bash command</h2>
</pre>

<p>You begin by specifying a <code>name</code> for your function. This is the name of your new command, you'll be able to run it later on by writing a simple command with that name.</p>
<p>After the command name go the <code>()</code> parenthesis. Some languages use these parenthesis to declare the arguments the function accepts: <strong>bash does not</strong>. The parenthesis should always be empty. They simply denote the fact that you're declaring a function.</p>
<p>After the command name go the <code>()</code> parentheses. Some languages use these parentheses to declare the arguments the function accepts: <strong>bash does not</strong>. The parentheses should always be empty. They simply denote the fact that you're declaring a function.</p>
<p>Next comes the compound command that will be executed each time you run the function.</p>
<p>To change the file descriptors of the script for the duration of running the function, you can optionally specify the function's custom file redirections.</p>
</dd>
Expand Down
10 changes: 5 additions & 5 deletions expansions.html
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ <h2>Pathname Expansion</h2>
<td>A set of characters within rectangular braces matches a single character, only if it's in the given set.</td>
</tr>
<tr>
<th><code class="syntax"><strong>[:</strong><var>classname</var><strong>:]</strong></code></th>
<th><code class="syntax"><strong>[[:</strong><var>classname</var><strong>:]]</strong></code></th>
<td>When there is a set of colons directly inside the rectangular braces, you can specify the name of a class of characters instead of having to enumerate each character yourself.<br>
Bash knows about various kinds of character classes. For example, if you use the <code>[:<var>alnum</var>:]</code> pattern, bash will match it against a character only if it is alphanumeric. Supported character classes include:<br>
Bash knows about various kinds of character classes. For example, if you use the <code>[[:<var>alnum</var>:]]</code> pattern, bash will match it against a character only if it is alphanumeric. Supported character classes include:<br>
<var>alnum</var>, <var>alpha</var>, <var>ascii</var>, <var>blank</var>, <var>cntrl</var>, <var>digit</var>, <var>graph</var>, <var>lower</var>, <var>print</var>, <var>punct</var>, <var>space</var>, <var>upper</var>, <var>word</var>, <var>xdigit</var></td>
</tr>
</table>
Expand Down Expand Up @@ -120,10 +120,10 @@ <h2>Pathname Expansion</h2>
<span class="prompt">$ </span><kbd>ls <mark>[0-9]</mark>*</kbd><em>In a character set, we can use <code>-</code> to indicate a range of characters. This will match</em>
<mark>0</mark>5 Between Angels and Insects.ogg<em>a pathname starting with one character between <code>0</code> and <code>9</code> followed by any other text.</em>
<mark>0</mark>7 Wake Up.ogg
<span class="prompt">$ </span><kbd>ls <mark>[:digit:][:digit:]</mark>*</kbd><em>Character classes are really nice because they speak for us: they tell us exactly</em>
<span class="prompt">$ </span><kbd>ls <mark>[[:digit:]][[:digit:]]</mark>*</kbd><em>Character classes are really nice because they speak for us: they tell us exactly</em>
<mark>05</mark> Between Angels and Insects.ogg<em>what our intent here is. We want any pathname that start with two digits.</em>
<mark>07</mark> Wake Up.ogg
<span class="prompt">$ </span><kbd>ls [:digit:][:digit:]</kbd><em>Your pattern needs to be complete! None of our filenames is only just a single digit.</em>
<span class="prompt">$ </span><kbd>ls [[:digit:]][[:digit:]]</kbd><em>Your pattern needs to be complete! None of our filenames is only just a single digit.</em>
<span class="prompt">$ </span>
</pre>

Expand Down Expand Up @@ -196,7 +196,7 @@ <h2>Pathname Expansion</h2>

<p>Extended glob patterns can be extremely useful at times, but they can also be confusing and misleading. Let's focus on the last example: why does <code>!(my)*.txt</code> expand the pathname <code>myscript.txt</code>? Isn't <code>!(my)</code> supposed to only match when the pathname does <em>not</em> have a <code>my</code> in this position? You are correct, it is! And yet, bash expands a pathname that begins with <code>my</code>!</p>

<p>The answer here is that bash will happily match this part of the pattern against the <code>m</code> at the beginning (which is not the same as <code>my</code>) or even empty space at the start of the filename. This means that in order for the pathname to still be eligible for expansion, the <em>rest of our pattern</em> needs to match against it the remaineder of
<p>The answer here is that bash will happily match this part of the pattern against the <code>m</code> at the beginning (which is not the same as <code>my</code>) or even empty space at the start of the filename. This means that in order for the pathname to still be eligible for expansion, the <em>rest of our pattern</em> needs to match against the remainder of
our pathname. And it so happens that we have a <code>*</code> glob right after the <code>!(my)</code> glob which will happily match the entirety of the filename. In this situation, the <code>!(my)</code> part matches against
the <code>m</code> character in the beginning of the name, the <code>*</code> matches against the <code>yscript</code> part, and the <code>.txt</code> suffix of the pattern matches against the trailing <code>.txt</code> of our pathname. The pattern matches the name, so the name is expanded! When we include the <code>*</code> inside the <code>!()</code> pattern, this no longer works and the match fails against this pathname:</p>

Expand Down
8 changes: 4 additions & 4 deletions inception.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ <h2>What's going on here? Text, terminals, bash, programs, input, output!</h2>
If you're still a bit dizzy from the speed (and otherwise!), let's take a step back and get a clear picture of what's going on. Depending on your level of familiarity with the matter, there may be a lot of new concepts here. Even if these concepts are not new to you, there is a good chance you don't know exactly how to frame them. If you're going to understand what exactly is going on when you run
code on your computer, it's vital that you have a good understanding of how the different concepts interact.</p>

<img src="img/terminal-bash.png" alt="The terminal program runs in the GUI, the bash program runs in the terminal.">
<img src="/img/terminal-bash.png" alt="The terminal program runs in the GUI, the bash program runs in the terminal.">

<p>When you start a terminal emulator program from your graphical user interface, you'll see a window open up with text in it. The text that displays in this window is both the output of programs running in the terminal as well as the characters you've sent to those programs using, for instance, your keyboard. The bash program is only one of many programs that can run in a terminal, so it is important to note that <em>bash is not what's making text appear on your screen</em>. The
terminal program takes care of that, taking text from bash and placing it in its window for you to see. The terminal may do the same for other programs running in the terminal, completely unrelated to bash, such as a mail program or an IRC client.</p>

<img src="img/terminal-more.png" alt="The terminal program can run other programs which in turn can run other programs, building a chain.">
<img src="/img/terminal-more.png" alt="The terminal program can run other programs which in turn can run other programs, building a chain.">

<p>It is sometimes difficult to tell just what programs are currently running in a terminal. In the example above, text from your keyboard goes through a long chain of programs, passed from one to the other, until it reaches its final destination (the <code>mail</code> program running on another computer at IP address <code>192.168.1.1</code>).<br>
I won't describe these programs in depth, the point here is that terminal programs all inter-connect and work together under the hood. Since there isn't much of a visual reminder about what's happening, it's important that you develop a good understanding of when programs start, communicate and end, so that you can properly understand the effects and side-effects of sending input to or receiving output from various programs in your text based user interface.</p>
Expand All @@ -135,7 +135,7 @@ <h2>So what exactly is a program and how does it connect to other programs?</h2>
<p>It may seem obvious at first, but upon second thought it's not immediately clear to most what a program really is. Additionally, we're going to try and avoid making claims in this guide that aren't explained, at least within our subject scope, such as the fact that programs "connect" with one another.</p>
<p>In short, a program is a set of pre-written instructions that can be executed by your system's <dfn>kernel</dfn>. A program gives instructions to the kernel directly. The kernel is technically also a program, but one that runs constantly and communicates with your hardware instead.</p>

<img src="img/process.png" alt="A process is a running program that can relays instructions to the kernel and has input and output connectors called FDs.">
<img src="/img/process.png" alt="A process is a running program that can relays instructions to the kernel and has input and output connectors called FDs.">

<p>A program generally lives on your disk, waiting to be started. When you "run" or "execute" a program, your kernel loads its pre-written instructions (its <dfn>code</dfn>) by creating a <dfn>process</dfn> for your program to work in. As we briefly saw in the previous section, your program can run many times simultaneously, each of those instances are running processes of your program. If a chocolate cake recipe is a program, then your process of baking a chocolate
cake with it is the program's process. A process relays the instructions in your program to the kernel. A process also
Expand All @@ -157,7 +157,7 @@ <h2>So what exactly is a program and how does it connect to other programs?</h2>
<p>A stream is information (specifically, <dfn>bytes</dfn>) flowing through the links between files, devices and processes in a running system. They can transport any kind of bytes, and the receiving end can only consume their bytes in the order they were sent. If I have a program that outputs names connected to another program, the second program can only see the second name after first reading the first name from the stream. When it's done reading the second name, the next thing in the
stream is the third name. Once a name is read from the stream, the program can store it somewhere if it may need it again later. Reading a name from the stream consumes those bytes from the stream and the stream advances. The stream cannot be rewound and the name cannot be re-read.</p>

<img src="img/streams.png" alt="Processes have file descriptors that connect to files, devices and other processes via streams.">
<img src="/img/streams.png" alt="Processes have file descriptors that connect to files, devices and other processes via streams.">

<p>In the above example, two bash processes are linked via a stream. The first bash process reads its input from the keyboard. It sends output on both standard output and standard error. Output on standard error is connected to the terminal display, while output on standard output is connected to the second process. Notice how the first process' <code>FD 1</code> connects to the second process' <code>FD 0</code>. The second process therefore consumes the first process'
standard output when it reads from its standard input. The second process' standard output in turn is connected to the terminal's display. Running this code in a terminal would show us something like this:</p>
Expand Down

0 comments on commit fac02c7

Please sign in to comment.