Move under www to ease rsync
This commit is contained in:
18
www/eps/hpr2649/hpr2649_bash10_ex1.sh
Executable file
18
www/eps/hpr2649/hpr2649_bash10_ex1.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Demonstration of the 'if' command
|
||||
#
|
||||
for fruit in banana apple pear kiwi; do
|
||||
if [ "$fruit" == "banana" ]; then
|
||||
echo "$fruit: don't eat the skin"
|
||||
elif [ "$fruit" == "apple" ]; then
|
||||
echo "$fruit: eat the skin or not, as you please"
|
||||
elif [ "$fruit" == "kiwi" ]; then
|
||||
echo "$fruit: most people remove the skin"
|
||||
else
|
||||
echo "$fruit: not sure how to handle this"
|
||||
fi
|
||||
done
|
||||
|
||||
exit
|
||||
16
www/eps/hpr2649/hpr2649_bash10_ex2.sh
Executable file
16
www/eps/hpr2649/hpr2649_bash10_ex2.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Demonstration of the 'case' command
|
||||
#
|
||||
for fruit in banana apple pear kiwi nectarine; do
|
||||
case $fruit in
|
||||
banana) echo "$fruit: don't eat the skin" ;;
|
||||
apple) echo "$fruit: eat the skin or not, as you please" ;;
|
||||
kiwi) echo "$fruit: most people remove the skin" ;;
|
||||
nectarine) echo "$fruit: leave the skin on and eat it" ;;
|
||||
*) echo "$fruit: not sure how to advise" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
exit
|
||||
25
www/eps/hpr2649/hpr2649_bash10_ex3.sh
Executable file
25
www/eps/hpr2649/hpr2649_bash10_ex3.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Further demonstration of the 'case' command with alternative clause
|
||||
# terminators
|
||||
#
|
||||
|
||||
i=704526
|
||||
|
||||
echo "Number given is: $i"
|
||||
|
||||
case $i in
|
||||
*0*) echo "it contains a 0" ;;&
|
||||
*1*) echo "it contains a 1" ;;&
|
||||
*2*) echo "it contains a 2" ;;&
|
||||
*3*) echo "it contains a 3" ;;&
|
||||
*4*) echo "it contains a 4" ;;&
|
||||
*5*) echo "it contains a 5" ;;&
|
||||
*6*) echo "it contains a 6" ;;&
|
||||
*7*) echo "it contains a 7" ;;&
|
||||
*8*) echo "it contains a 8" ;;&
|
||||
*9*) echo "it contains a 9" ;;
|
||||
esac
|
||||
|
||||
exit
|
||||
290
www/eps/hpr2649/hpr2649_full_shownotes.html
Executable file
290
www/eps/hpr2649/hpr2649_full_shownotes.html
Executable file
@@ -0,0 +1,290 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="pandoc">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
<meta name="author" content="Dave Morriss">
|
||||
<title>More ancillary Bash tips - 10 (HPR Show 2649)</title>
|
||||
<style type="text/css">code{white-space: pre;}</style>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link rel="stylesheet" href="http://hackerpublicradio.org/css/hpr.css">
|
||||
</head>
|
||||
|
||||
<body id="home">
|
||||
<div id="container" class="shadow">
|
||||
<header>
|
||||
<h1 class="title">More ancillary Bash tips - 10 (HPR Show 2649)</h1>
|
||||
<h2 class="author">Dave Morriss</h2>
|
||||
<hr/>
|
||||
</header>
|
||||
|
||||
<main id="maincontent">
|
||||
<article>
|
||||
<header>
|
||||
<h1>Table of Contents</h1>
|
||||
<nav id="TOC">
|
||||
<ul>
|
||||
<li><a href="#making-decisions-in-bash">Making decisions in Bash</a></li>
|
||||
<li><a href="#looping-constructs">Looping Constructs</a><ul>
|
||||
<li><a href="#while-command"><code>while</code> command</a></li>
|
||||
<li><a href="#until-command"><code>until</code> command</a></li>
|
||||
<li><a href="#examples-of-while-and-until">Examples of <code>while</code> and <code>until</code></a><ul>
|
||||
<li><a href="#example-1">Example 1</a></li>
|
||||
<li><a href="#example-2">Example 2</a></li>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
<li><a href="#conditional-constructs">Conditional Constructs</a><ul>
|
||||
<li><a href="#if-command"><code>if</code> command</a></li>
|
||||
<li><a href="#case-command"><code>case</code> command</a></li>
|
||||
<li><a href="#examples-of-if-and-case">Examples of <code>if</code> and <code>case</code></a><ul>
|
||||
<li><a href="#example-3">Example 3</a></li>
|
||||
<li><a href="#example-4">Example 4</a></li>
|
||||
<li><a href="#example-5">Example 5</a></li>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
<li><a href="#lists-of-commands">Lists of Commands</a><ul>
|
||||
<li><a href="#and-lists">AND Lists</a></li>
|
||||
<li><a href="#or-lists">OR Lists</a><ul>
|
||||
<li><a href="#an-insight-into-how-these-lists-behave">An insight into how these lists behave</a></li>
|
||||
<li><a href="#examples">Examples</a></li>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
<li><a href="#links">Links</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
<h2 id="making-decisions-in-bash">Making decisions in Bash</h2>
|
||||
<p>This is my tenth contribution to the <a href="http://hackerpublicradio.org/series.php?id=42" title="*Bash Scripting* series"><em>Bash Scripting</em></a> series under the heading of <em>Bash Tips</em>. The previous episodes are listed below in the <a href="#links">Links</a> section.</p>
|
||||
<p>We are currently looking at decision making in Bash, and in the last episode we examined the tests themselves. In this episode we’ll look at the constructs that use these tests: looping constructs, conditional constructs and lists of commands.</p>
|
||||
<p><strong>Note</strong>: this episode and the preceding one were originally recorded as a single episode, but because it was so long it was split into two. As a consequence the audio contains references to examples such as <code>bash9_ex2.sh</code> where the true name is <code>bash10_ex1.sh</code>. The notes have been updated as necessary but not the audio.</p>
|
||||
<h2 id="looping-constructs">Looping Constructs</h2>
|
||||
<p>Bash supports a number of commands which can be used to build loops. These are documented in the <em>Looping Constructs</em> section of the <a href="https://www.gnu.org/software/bash/manual/bash.html#Looping-Constructs" title="Bash Looping Constructs">GNU Bash Manual</a>. We will look only at <code>while</code> and <code>until</code> here because they contain tests. We will leave <code>for</code> loops until a later episode.</p>
|
||||
<h3 id="while-command"><code>while</code> command</h3>
|
||||
<p>The syntax of the <code>while</code> command is:</p>
|
||||
<blockquote>
|
||||
<p><b>while</b> <em>test_commands</em><br />
|
||||
<b>do</b><br />
|
||||
<em>commands</em><br />
|
||||
<b>done</b></p>
|
||||
</blockquote>
|
||||
<p>The <em>commands</em> are executed as long as <em>test_commands</em> return an exit status which is zero (loop while the result is <em>true</em>).</p>
|
||||
<h3 id="until-command"><code>until</code> command</h3>
|
||||
<p>The syntax of the <code>until</code> command is:</p>
|
||||
<blockquote>
|
||||
<p><b>until</b> <em>test_commands</em><br />
|
||||
<b>do</b><br />
|
||||
<em>commands</em><br />
|
||||
<b>done</b></p>
|
||||
</blockquote>
|
||||
<p>The <em>commands</em> are executed as long as <em>test_commands</em> return an exit status which is non-zero (loop until the result is <em>true</em>).</p>
|
||||
<h3 id="examples-of-while-and-until">Examples of <code>while</code> and <code>until</code></h3>
|
||||
<h4 id="example-1">Example 1</h4>
|
||||
<p>The following code snippet will print variable <code>i</code> and increment it while its value is less than 5, so it will output the numbers 0..4:</p>
|
||||
<pre><code>i=0
|
||||
while [ "$i" -lt 5 ]; do
|
||||
echo "$i"
|
||||
((i++))
|
||||
done</code></pre>
|
||||
<p>Note that in this example the <code>while</code> and <code>do</code> parts are both on the same line, separated by a semicolon. Also, as mentioned in the last show, the quotes around <code>"$i"</code> are advisable in case the variable is null, but if the variable is not initialised the loop will fail whether the quotes are used or not. Even the <code>shellcheck</code> tool I use to check my Bash scripts does not complain about missing quotes here.</p>
|
||||
<h4 id="example-2">Example 2</h4>
|
||||
<p>The next snippet will start with variable <code>i</code> set to 5 and decrement it down to zero:</p>
|
||||
<pre><code>i=5
|
||||
until [ "$i" -eq 0 ]; do
|
||||
echo "$i"
|
||||
((i--))
|
||||
done</code></pre>
|
||||
<p>In this case the last value printed will be 1, after which <code>i</code> will be decremented to 0, which will stop the loop.</p>
|
||||
<h2 id="conditional-constructs">Conditional Constructs</h2>
|
||||
<p>Bash offers three commands under this heading, two of which have a conditional component. The commands are <code>if</code>, <code>case</code> and <code>select</code>. They are documented in the <em>Conditional Constructs</em> section of the <a href="https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructs" title="Bash Conditional Constructs">GNU Bash Manual</a>. We will look only at <code>if</code> and <code>case</code> in this episode and will leave <code>select</code> until a later episode.</p>
|
||||
<h3 id="if-command"><code>if</code> command</h3>
|
||||
<p>This command has the syntax:</p>
|
||||
<blockquote>
|
||||
<p><b>if</b> <em>test_commands_1</em><br />
|
||||
<b>then</b><br />
|
||||
<em>commands_1</em><br />
|
||||
<b>elif</b> <em>test_commands_2</em><br />
|
||||
<b>then</b><br />
|
||||
<em>commands_2</em><br />
|
||||
<b>else</b><br />
|
||||
<em>commands_3</em><br />
|
||||
<b>fi</b></p>
|
||||
</blockquote>
|
||||
<p>If <em>test_commands_1</em> returns a status of zero then <em>commands_1</em> will be executed and the <code>if</code> command will terminate. If the status is non-zero then any <code>elif</code> part will be tested, and the associated commands (<em>commands_2</em> in this example) executed if the result is <em>true</em>. There may be zero or more of these <code>elif</code> parts.</p>
|
||||
<p>Once the <code>if</code> and any <code>elif</code> parts are tested and they all return <em>false</em>, the commands in the <code>else</code> part (<em>commands_3</em> here) will be executed. There may be zero or one <code>else</code> parts.</p>
|
||||
<p>Note that the <code>then</code> part can be written on the same line as the <code>if</code>/<code>elif</code>, when separated by a semicolon.</p>
|
||||
<h3 id="case-command"><code>case</code> command</h3>
|
||||
<p>The syntax of the <code>case</code> command is as follows:</p>
|
||||
<blockquote>
|
||||
<p><b>case</b> <em>word</em> <b>in</b><br />
|
||||
<em>pattern_list_1</em> ) <em>command_list_1</em> ;;<br />
|
||||
<em>pattern_list_2</em> ) <em>command_list_2</em> ;;<br />
|
||||
<b>esac</b></p>
|
||||
</blockquote>
|
||||
<p>The <code>case</code> command will selectively execute the <em>command_list</em> corresponding to the first <em>pattern_list</em> that matches <em>word</em>.</p>
|
||||
<p>If a <em>pattern_list</em> contains multiple patterns then they are separated by the <code>|</code> character. The patterns are the <em>Glob</em> patterns we have already seen (<a href="http://hackerpublicradio.org/eps/hpr2278" title="Some supplementary Bash tips">show 2278</a>). The <em>pattern_list</em> is terminated by the right parenthesis (and can be preceded by a left parenthesis if desired). The list of <em>patterns</em> and an associated <em>command_list</em> is known as a <em>clause</em>.</p>
|
||||
<p>There is no limit to the number of <code>case</code> clauses. The first pattern that matches determines the <em>command_list</em> that is executed. There is no default pattern, but making <code>'*'</code> the final one – a pattern that will always match – achieves the same thing.</p>
|
||||
<p>The clause terminator must be one of <code>';;'</code>, <code>';&'</code>, or <code>';;&'</code>, as explained below:</p>
|
||||
<table>
|
||||
<colgroup>
|
||||
<col style="width: 14%" />
|
||||
<col style="width: 85%" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th style="text-align: left;">Terminator</th>
|
||||
<th style="text-align: left;">Meaning</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;"><code>;;</code></td>
|
||||
<td style="text-align: left;">no subsequent matches are attempted after the first pattern match</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: left;"><code>;&</code></td>
|
||||
<td style="text-align: left;">execution continues with the <em>command_list</em> associated with the next clause, if any</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;"><code>;;&</code></td>
|
||||
<td style="text-align: left;">causes the shell to test the patterns in the next clause, if any, and execute any associated <em>command_list</em> on a successful match</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3 id="examples-of-if-and-case">Examples of <code>if</code> and <code>case</code></h3>
|
||||
<h4 id="example-3">Example 3</h4>
|
||||
<p>In this example shows the full range of this structured command <code>'if'</code> with <code>elif</code> and <code>else</code> branches:</p>
|
||||
<pre><code>fruit="apple"
|
||||
if [ "$fruit" == "banana" ]; then
|
||||
echo "$fruit: don't eat the skin"
|
||||
elif [ "$fruit" == "apple" ]; then
|
||||
echo "$fruit: eat the skin or not, as you please"
|
||||
elif [ "$fruit" == "kiwi" ]; then
|
||||
echo "$fruit: most people remove the skin"
|
||||
else
|
||||
echo "$fruit: not sure how to advise"
|
||||
fi</code></pre>
|
||||
<p>See the downloadable example script <a href="hpr2649_bash10_ex1.sh">bash10_ex1.sh</a><a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a> which uses the above <code>if</code> structure in a <code>for</code> loop. Run it yourself to see what it does.</p>
|
||||
<h4 id="example-4">Example 4</h4>
|
||||
<p>Here is the same idea using a <code>case</code> command:</p>
|
||||
<pre><code>fruit="apple"
|
||||
case $fruit in
|
||||
banana) echo "$fruit: don't eat the skin" ;;
|
||||
apple) echo "$fruit: eat the skin or not, as you please" ;;
|
||||
kiwi) echo "$fruit: most people remove the skin";;
|
||||
*) echo "$fruit: not sure how to advise"
|
||||
esac</code></pre>
|
||||
<p>See the downloadable example script <a href="hpr2649_bash10_ex2.sh">bash10_ex2.sh</a><a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a> which uses a <code>case</code> command similar to the above in a <code>for</code> loop.</p>
|
||||
<h4 id="example-5">Example 5</h4>
|
||||
<p>This example has been added since the audio was recorded to give an example of the use of the <code>;;&</code> clause terminator in a <code>case</code> command.</p>
|
||||
<p>The following downloadable example (<a href="hpr2649_bash10_ex3.sh">bash10_ex3.sh</a>) demonstrates this:</p>
|
||||
<pre><code>$ cat bash10_ex3.sh
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Further demonstration of the 'case' command with alternative clause
|
||||
# terminators
|
||||
#
|
||||
|
||||
i=704526
|
||||
|
||||
echo "Number given is: $i"
|
||||
|
||||
case $i in
|
||||
*0*) echo "it contains a 0" ;;&
|
||||
*1*) echo "it contains a 1" ;;&
|
||||
*2*) echo "it contains a 2" ;;&
|
||||
*3*) echo "it contains a 3" ;;&
|
||||
*4*) echo "it contains a 4" ;;&
|
||||
*5*) echo "it contains a 5" ;;&
|
||||
*6*) echo "it contains a 6" ;;&
|
||||
*7*) echo "it contains a 7" ;;&
|
||||
*8*) echo "it contains a 8" ;;&
|
||||
*9*) echo "it contains a 9" ;;
|
||||
esac
|
||||
|
||||
exit
|
||||
$ ./bash10_ex3.sh
|
||||
Number given is: 704526
|
||||
it contains a 0
|
||||
it contains a 2
|
||||
it contains a 4
|
||||
it contains a 5
|
||||
it contains a 6
|
||||
it contains a 7</code></pre>
|
||||
<p>The script sets variable <code>'i'</code> to a 6-digit number. The number is displayed with an <code>echo</code> command. The <code>case</code> command tests the variable with glob patterns containing all of the digits 0-9. Each case clause (except the last) is terminated with the <code>;;&</code> sequence which means that each clause is invoked regardless of the success or failure of the preceding one.</p>
|
||||
<p>The end result is that every pattern is tested and those that match generate output. If the case clauses had used the usual <code>;;</code> terminators then the <code>case</code> command would exit after the first match.</p>
|
||||
<h2 id="lists-of-commands">Lists of Commands</h2>
|
||||
<p>Bash commands can be typed in lists. The simplest list is just a series of commands (or pipelines - a subject we will look at more in later shows in the <em>Bash Tips</em> series), each separated by a newline.</p>
|
||||
<p>However, there are other list separators such as <code>';'</code>, <code>'&'</code>, <code>'&&'</code>, and <code>'||'</code>. The first two, <code>';'</code> and <code>'&'</code> are not really relevant to decision making, so we will omit these for now. However so-called <em>AND</em> and <em>OR</em> lists are relevant. These consist of commands or pipelines separated by <code>'&&'</code> (logical <em>AND</em>), and <code>'||'</code> (logical <em>OR</em>).</p>
|
||||
<h3 id="and-lists">AND Lists</h3>
|
||||
<p>An AND list has the form:</p>
|
||||
<pre><code>command1 && command2</code></pre>
|
||||
<p><em>command2</em> is executed if, and only if, <em>command1</em> returns an exit status of zero.</p>
|
||||
<h3 id="or-lists">OR Lists</h3>
|
||||
<p>An OR list has the form</p>
|
||||
<pre><code>command1 || command2</code></pre>
|
||||
<p><em>command2</em> is executed if, and only if, <em>command1</em> returns a non-zero exit status.</p>
|
||||
<h4 id="an-insight-into-how-these-lists-behave">An insight into how these lists behave</h4>
|
||||
<p>These operators <em>short circuit</em>:</p>
|
||||
<ul>
|
||||
<li>in the case of <code>'&&'</code> an attempt is being made to determine the result of applying a logical <em>AND</em> operation between the two operands. They both need to be <em>true</em> before the overall result is <em>true</em>. If the first operand (<em>command1</em>) is <em>false</em> then there is no need to compute the second result, the overall result <u>must</u> be <em>false</em>, so there is a <em>short circuit</em>.</li>
|
||||
<li>in the case of <code>'||'</code> either or both of the operands of the logical <em>OR</em> operation can be <em>true</em> to give an overall result of <em>true</em>. Thus if <em>command1</em> returns <em>true</em> nothing else need be done to determine the overall result, whereas if <em>command1</em> is <em>false</em>, then <em>command2</em> must be executed to determine the overall result.</li>
|
||||
</ul>
|
||||
<p>I found it useful to consider this when using these types of lists, so I am sharing it with you.</p>
|
||||
<h4 id="examples">Examples</h4>
|
||||
<p>It is common to see these used in scripts as a simplified form of decision with an explicit test as <em>command1</em>. For example, you might see:</p>
|
||||
<pre><code>[ -e /some/file ] || exit 1</code></pre>
|
||||
<p>Here the script will exit if the named file does not exist (we will look at the <code>-e</code> operator in the next episode). Note that it exits with a non-zero result so that the script itself could be used as <em>command1</em> in an AND or OR list.</p>
|
||||
<p>It is possible to execute several commands instead of just the <code>exit</code> by grouping them in curly braces (<code>'{}'</code>). For example:</p>
|
||||
<pre><code>[ -e /home/user1/somefile ] || { echo "Unable to find /home/user1/somefile"; exit 1; }</code></pre>
|
||||
<p>It is necessary to type a space<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a> after <code>'{'</code> and before <code>'}'</code>. Also each command within the braces must end with a semicolon (or a newline).</p>
|
||||
<p>This example could be written as follows, remembering that <code>test</code> is an alternative to <code>'[...]'</code>:</p>
|
||||
<pre><code>test -e /home/user1/somefile || {
|
||||
echo "Unable to find /home/user1/somefile"
|
||||
exit 1
|
||||
}</code></pre>
|
||||
<p>As we have already seen it is possible to use any test or command which returns an exit status of zero or non-zero as <em>command1</em> in a list. So the following command list is equivalent to the <code>'if'</code> example above:</p>
|
||||
<pre><code>grep -q -e '^banana$' fruit.txt && echo "Found a banana"</code></pre>
|
||||
<p>However, it is my opinion that it is clearer and more understandable when the <code>'if'</code> alternative is used.</p>
|
||||
<h2 id="links">Links</h2>
|
||||
<ul>
|
||||
<li><a href="https://www.gnu.org/software/bash/manual/bash.html">“<em>GNU BASH Reference Manual</em>”</a>
|
||||
<ul>
|
||||
<li><a href="https://www.gnu.org/software/bash/manual/bash.html#Looping-Constructs">“Bash Looping Constructs”</a></li>
|
||||
<li><a href="https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructs">“Bash Conditional Constructs”</a></li>
|
||||
<li><a href="https://www.gnu.org/software/bash/manual/bash.html#Bourne-Shell-Builtins">“Bourne Shell Builtins”</a></li>
|
||||
</ul></li>
|
||||
<li><a href="http://hackerpublicradio.org/series.php?id=42">HPR series: <em>Bash Scripting</em></a></li>
|
||||
<li>Previous episodes under the heading <em>Bash Tips</em>:
|
||||
<ol>
|
||||
<li><a href="http://hackerpublicradio.org/eps/hpr1648">HPR episode 1648 “<em>Bash parameter manipulation</em>”</a></li>
|
||||
<li><a href="http://hackerpublicradio.org/eps/hpr1843">HPR episode 1843 “<em>Some Bash tips</em>”</a></li>
|
||||
<li><a href="http://hackerpublicradio.org/eps/hpr1884">HPR episode 1884 “<em>Some more Bash tips</em>”</a></li>
|
||||
<li><a href="http://hackerpublicradio.org/eps/hpr1903">HPR episode 1903 “<em>Some further Bash tips</em>”</a></li>
|
||||
<li><a href="http://hackerpublicradio.org/eps/hpr1951">HPR episode 1951 “<em>Some additional Bash tips</em>”</a></li>
|
||||
<li><a href="http://hackerpublicradio.org/eps/hpr2045">HPR episode 2045 “<em>Some other Bash tips</em>”</a></li>
|
||||
<li><a href="http://hackerpublicradio.org/eps/hpr2278">HPR episode 2278 “<em>Some supplementary Bash tips</em>”</a></li>
|
||||
<li><a href="http://hackerpublicradio.org/eps/hpr2293">HPR episode 2293 “<em>More supplementary Bash tips</em>”</a></li>
|
||||
<li><a href="http://hackerpublicradio.org/eps/hpr2639">HPR episode 2639 “<em>Some ancillary Bash tips - 9</em>”</a></li>
|
||||
</ol></li>
|
||||
<li>Resources:
|
||||
<ul>
|
||||
<li>Examples: <a href="hpr2649_bash10_ex1.sh">bash10_ex1.sh</a>, <a href="hpr2649_bash10_ex2.sh">bash10_ex2.sh</a>, <a href="hpr2649_bash10_ex3.sh">bash10_ex3.sh</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<section class="footnotes">
|
||||
<hr />
|
||||
<ol>
|
||||
<li id="fn1"><p>The audio refers to the examples by the name they had before the one long show was split into two. What was <code>bash9_ex2.sh</code> has become <code>bash10_ex1.sh</code>.<a href="#fnref1" class="footnote-back">↩</a></p></li>
|
||||
<li id="fn2"><p>The audio refers to the examples by the name they had before the one long show was split into two. What was <code>bash9_ex3.sh</code> has become <code>bash10_ex2.sh</code>.<a href="#fnref2" class="footnote-back">↩</a></p></li>
|
||||
<li id="fn3"><p>Technically this should be <u>whitespace</u> which means one or more spaces, tabs or newlines.<a href="#fnref3" class="footnote-back">↩</a></p></li>
|
||||
</ol>
|
||||
</section>
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user