<?php include "HEADER.php"; ?>

<h1>Bash Shell Scripting </h1>

<p><b>These notes have been replaced by <a href="https://paulgorman.org/technical/bash.txt">https://paulgorman.org/technical/bash.txt</a></b>.</p>

<h2>Shell scripts</h2>

<p>Shell scripts should be executable (<code>chmod u+x myscript.sh</code>), and the first line of the script should be a shebang interpreter directive pointing to the absolute path of bash.</p>

<pre>
#!/bin/bash
echo "Hello, world!"</pre>

<h2>Comments</h2>

<pre>
# Hash marks precede comments.
echo "Hello, world!"</pre>

<h2>Variables, Quotation Marks, Interpolation &amp; Substitution</h2>

<pre>~$ foo=bar
~$ echo "The value of 'foo' is $foo."
The value of 'foo' is bar.
~$ myarray=(red blue green); for c in ${myarray[@]}; do echo $c; done
red
blue
green
</pre>

<p>N.b. <code>=</code> functions as either assignment or equality test, depending on the context.</p>

<p>Double-quoted things ("foo $bar") are treated as a single argument or string, regardless of internal whitespace. Variables inside double quotes are interpolated ($foo would be evaluated).</p>

<p>Single-quoted things ('foo $bar') are also treated as a single argument or string, but variables are <em>note</em> interpolated.</p>

<p>Don't confuse single quotes with backticks (`). Backticks replace a command with the output of that command:</p>

<pre>~$ echo `date`
Fri Jan 11 15:10:00 EST 2013</pre>

<p><code>$()</code> does the same thing as backticks, is less ambiguous, and can be nested. <code>echo $(date)</code> is functionally equivalent to the above.</p>

<p>Bash also does arithmetic expansion for expressions between <code>$((</code> and <code>))</code>:</p>

<pre>~$ echo $((2*2))
4</pre>


<h2>Some of the Built-in Variables</h2>

<dl>
<dt>$0</dt>
<dd>Name of the shell script.</dd>
<dt>$-</dt>
<dd>Flags passed to the script.</dd>
<dt>$1-$<i>N</i></dt>
<dd>Arguments passed from the command line.</dd>
<dt>$#</dt>
<dd>The number/quantity of command line arguments ($1-$<i>N</i>).</dd>
<dt>$*</dt>
<dd>Command line arguments $1-$<i>N</i>.</dd>
<dt>"$@"</dt>
<dd>Command line arguments $1-$<i>N</i>, individually quoted.</dd>
<dt>$?</dt>
<dd>Return value of last command. Success returns zero, error returns non-zero.</dd>
<dt>$$</dt>
<dd>PID of this script.</dd>
<dt></dt>
<dd></dd>
</dl>

<h2>Conditionals &amp; Loops</h2>

<pre>
if [[ -e "fileexists.txt" ]]; then
    echo "The file exists.";
elif [[ $a = $b ]]; then
    echo "They're equal.";
elif [[ -s "nonemptyfile.txt" ]]; then
    echo "A non-empty file exists.";
else
    echo "The file does not exist.";
fi
</pre>

<pre>
for f in ~/tmp/*;
do
    if [[ -d $f ]]; then
        echo "$f is a directory.";
    fi;
done
</pre>

<pre>
n=0;
while [[ $n -ne 42 ]];
do
    echo $n;
    n=$(( $n + 1 ));
done
</pre>

<pre>
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    *)
        echo $"Usage: $0 {start|stop}"
        exit 1
esac
</pre>

<p>The <code>[[...]]</code> construct evaluates expressions like the <code>test</code> command (<a href="http://www.unix.com/man-page/Linux/1/test/">man test</a>).</p>

<h2>Further Reading</h2>

<ul>
<li><a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/index.html">Bash Guide for Beginners (TLDP)</a></li>
<li><a href="http://tldp.org/LDP/abs/html/index.html">Advanced Bash Scripting Guide (TLDP)</a></li>
<li><a href="http://www.ibm.com/developerworks/linux/library/l-bash2/index.html">Bash by example (IBM)</a></li>
<li><a href="http://www.gnu.org/software/bash/manual/bashref.html">GNU Bash Reference</a></li>
<li><a href=""></a></li>
</ul>

<?php include "../FOOTER.php"; ?>
