mirror of https://github.com/tLDP/LDP
updated
This commit is contained in:
parent
dbc098bbd4
commit
702659bde7
|
@ -6,6 +6,66 @@
|
|||
http://personal.riverusers.com/~thegrendel/Change.log
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Version 2.1
|
||||
'HUCKLEBERRY' release, 09/14/03
|
||||
|
||||
1) In Appendix B, "Reference Cards:
|
||||
Fixups --
|
||||
(thanks to errors brought to my attention by Heiner Steven).
|
||||
|
||||
2) In Appendix B, "Reference Cards:
|
||||
Added "Miscellaneous Construct" table.
|
||||
Added variable prefix matching to "Parameter Substitution" table.
|
||||
|
||||
3) In "Internal Variables" chapter"
|
||||
Noted that "$*" must be quoted to differentiate it from "$@" variable,
|
||||
and added a case to "arglist.sh" example to demonstrate this.
|
||||
(Thanks, Heiner Steven.)
|
||||
|
||||
4) In "Command Substitution" chapter:
|
||||
Added note about the invocation of a subshell.
|
||||
Likewise added note in "setting variable to a file" in-line example.
|
||||
(Thanks, Paul Heffner.)
|
||||
Removed erroneous comment from in-line example of
|
||||
setting a variable to contents of a file.
|
||||
(Thanks, Anthony Richardson.)
|
||||
|
||||
5) In "Arrays" chapter:
|
||||
Added "script-array.sh" example.
|
||||
(Thanks, Chris Martin, for the inspiration.)
|
||||
|
||||
6) In "System Resources" subsection of "System and Administrative
|
||||
Commands":
|
||||
Fixed minor error ("while 1") in 'ulimit' illustrative script.
|
||||
(Thanks Emmanuel Chantreau)
|
||||
|
||||
7) In "Subshells" chapter:
|
||||
Added a paragraph of commentary concerning external commands and Bash
|
||||
builtins.
|
||||
|
||||
8) In "Special Characters" chapter:
|
||||
Elaborated example of ';' usage.
|
||||
|
||||
9) In "Gotchas" chapter:
|
||||
Added in-line example of problem caused by piping to a loop.
|
||||
(Thanks Anthony Richardson.)
|
||||
|
||||
10) In "System and Administrative Commands" chapter:
|
||||
Added more info to "sar" listing.
|
||||
|
||||
11) In "Writing Scripts" section of "Exercises" appendix:
|
||||
Added "Monitoring Processes" exercise.
|
||||
|
||||
12) In "Recursion" section of "Oddities" chapter:
|
||||
Added Anthony Richardson's "usrmnt.sh" example.
|
||||
(Thanks!)
|
||||
|
||||
13) Slight modifications to certain example files for clarification.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Version 2.0
|
||||
'GOOSEBERRY' release, 08/24/03
|
||||
|
||||
|
@ -52,7 +112,7 @@ bumped up to a major version. This is now officially a "mature" project.
|
|||
by disabling parameter substitution within the body of a 'here document.'
|
||||
(Thanks, Albert Reiner, for the idea.)
|
||||
|
||||
10) In "Miscellaneous" subsection of "System and Administrative Commands"
|
||||
10) In "Miscellaneous" subsection of "System and Administrative Commands":
|
||||
chapter:
|
||||
Added listing for "dialog" toolsets.
|
||||
|
||||
|
|
|
@ -272,6 +272,8 @@ Uncomment line below to generate index.
|
|||
<!ENTITY directoryinfo SYSTEM "directory-info.sh">
|
||||
<!ENTITY embarr SYSTEM "embedded-arrays.sh">
|
||||
<!ENTITY generatescript SYSTEM "generate-script.sh">
|
||||
<!ENTITY scriptarray SYSTEM "script-array.sh">
|
||||
<!ENTITY usrmnt SYSTEM "usrmnt.sh">
|
||||
<!ENTITY dialog SYSTEM "dialog.sh">
|
||||
<!ENTITY evalex SYSTEM "eval.example">
|
||||
<!ENTITY namesdata SYSTEM "names.data">
|
||||
|
@ -294,8 +296,8 @@ Uncomment line below to generate index.
|
|||
</affiliation>
|
||||
</author>
|
||||
|
||||
<releaseinfo>2.0</releaseinfo>
|
||||
<pubdate>24 August 2003</pubdate>
|
||||
<releaseinfo>2.1</releaseinfo>
|
||||
<pubdate>14 September 2003</pubdate>
|
||||
|
||||
|
||||
<revhistory>
|
||||
|
@ -420,8 +422,15 @@ Uncomment line below to generate index.
|
|||
<date>24 August 2003</date>
|
||||
<authorinitials>mc</authorinitials>
|
||||
<revremark>'GOOSEBERRY' release: Major update.</revremark>
|
||||
|
||||
</revision>
|
||||
|
||||
<revision>
|
||||
<revnumber>2.1</revnumber>
|
||||
<date>14 September 2003</date>
|
||||
<authorinitials>mc</authorinitials>
|
||||
<revremark>'HUCKLEBERRY' release: bugfixes and more material.</revremark>
|
||||
</revision>
|
||||
|
||||
</revhistory>
|
||||
|
||||
|
||||
|
@ -445,7 +454,7 @@ Uncomment line below to generate index.
|
|||
linkend="bzipref">bzip2-ed</link> <quote>tarball</quote>
|
||||
including both the SGML source and
|
||||
rendered HTML, may be downloaded from <ulink
|
||||
url="http://personal.riverusers.com/~thegrendel/abs-guide-2.0.tar.bz2">
|
||||
url="http://personal.riverusers.com/~thegrendel/abs-guide-2.1.tar.bz2">
|
||||
the author's home site</ulink>. See the <ulink
|
||||
url="http://personal.riverusers.com/~thegrendel/Change.log">change
|
||||
log</ulink> for a revision history.</para>
|
||||
|
@ -979,7 +988,17 @@ echo $(( 2#101011 )) # Base conversion, not a comment.
|
|||
the same line.</para>
|
||||
</formalpara>
|
||||
|
||||
<para><programlisting>echo hello; echo there</programlisting></para>
|
||||
<para>
|
||||
<programlisting>echo hello; echo there
|
||||
|
||||
|
||||
if [ -x "$filename" ]; then # Note that "if" and "then" need separation.
|
||||
# Why?
|
||||
echo "File $filename exists."; cp $filename $filename.bak
|
||||
else
|
||||
echo "File $filename not found."; touch $filename
|
||||
fi; echo "File test complete."</programlisting>
|
||||
</para>
|
||||
|
||||
<para>Note that the <quote><token>;</token></quote> sometimes
|
||||
needs to be <link linkend="escp">escaped</link>.</para>
|
||||
|
@ -6016,9 +6035,9 @@ echo "Last command argument processed = $last_cmd_arg"
|
|||
</indexterm>
|
||||
<listitem><para></para>
|
||||
<para>The <varname>$PPID</varname> of a process is
|
||||
the process id (<varname>pid</varname>) of its parent process.
|
||||
the process ID (<varname>pid</varname>) of its parent process.
|
||||
|
||||
<footnote><para>The pid of the currently running script is
|
||||
<footnote><para>The PID of the currently running script is
|
||||
<varname>$$</varname>, of course.</para></footnote>
|
||||
</para>
|
||||
|
||||
|
@ -6428,8 +6447,10 @@ echo "Last command argument processed = $last_cmd_arg"
|
|||
<secondary>positional</secondary>
|
||||
<tertiary>all</tertiary>
|
||||
</indexterm>
|
||||
<listitem><para>All of the positional parameters, seen as a single
|
||||
word</para>
|
||||
<listitem>
|
||||
<para>All of the positional parameters, seen as a single word</para>
|
||||
<note><para><quote><varname>$*</varname></quote> must be
|
||||
quoted.</para></note>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -6446,12 +6467,18 @@ echo "Last command argument processed = $last_cmd_arg"
|
|||
<primary>positional parameter</primary>
|
||||
<secondary>all</secondary>
|
||||
</indexterm>
|
||||
<listitem><para>Same as <token>$*</token>, but each parameter is a
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>Same as <token>$*</token>, but each parameter is a
|
||||
quoted string, that is, the parameters are passed on
|
||||
intact, without interpretation or expansion. This means,
|
||||
among other things, that each parameter in the argument
|
||||
list is seen as a separate word.</para>
|
||||
|
||||
<note><para>Of course, <quote><varname>$@</varname></quote>
|
||||
should be quoted.</para></note>
|
||||
|
||||
<example id="arglist">
|
||||
<title><command>arglist</command>: Listing arguments with $* and $@</title>
|
||||
<programlisting>&arglist;</programlisting>
|
||||
|
@ -9607,7 +9634,7 @@ do
|
|||
operation-2
|
||||
...
|
||||
operation-n
|
||||
# Need a way to break out of loop.
|
||||
# Need a way to break out of loop or script will hang.
|
||||
done</programlisting></para>
|
||||
|
||||
</listitem>
|
||||
|
@ -9993,7 +10020,7 @@ wait</programlisting>
|
|||
process</quote>, that is, a process whose <link
|
||||
linkend="forkref">parent</link> has terminated, cannot be
|
||||
killed (you can't kill something that is already dead),
|
||||
but <command>init</command> will usually clean it up
|
||||
but <command>init</command> will generally clean it up
|
||||
sooner or later.</para></note>
|
||||
|
||||
</listitem>
|
||||
|
@ -10159,6 +10186,8 @@ wait</programlisting>
|
|||
<chapter id="external">
|
||||
<title>External Filters, Programs and Commands</title>
|
||||
|
||||
<para><anchor id="externalref"></para>
|
||||
|
||||
<para>Standard UNIX commands make shell scripts more versatile. The
|
||||
power of scripts comes from coupling system commands and shell
|
||||
directives with simple programming constructs.</para>
|
||||
|
@ -16366,11 +16395,13 @@ exit 0
|
|||
<secondary>system activity report</secondary>
|
||||
</indexterm>
|
||||
<listitem>
|
||||
<para>Invoking <command>sar</command> (system activity report)
|
||||
gives a very detailed rundown on system statistics.
|
||||
This command is found on some commercial UNIX
|
||||
systems, but is not part of the base Linux
|
||||
distribution. It is contained in the <ulink
|
||||
<para>Invoking <command>sar</command> (System Activity Reporter)
|
||||
gives a very detailed rundown on system statistics. The
|
||||
Santa Cruz Operation (SCO) released
|
||||
<command>sar</command> as Open Source in June, 1999.</para>
|
||||
|
||||
<para>This command is not part of the base Linux distribution,
|
||||
but may be obtained as part of the<ulink
|
||||
url="http://perso.wanadoo.fr/sebastien.godard/">
|
||||
sysstat utilities</ulink> package, written by <ulink
|
||||
url="mailto:sebastien.godard@wanadoo.fr">Sebastien
|
||||
|
@ -16519,7 +16550,7 @@ exit 0
|
|||
<listitem>
|
||||
<para><replaceable>P</replaceable>rocess
|
||||
<replaceable>S</replaceable>tatistics: lists currently
|
||||
executing processes by owner and PID (process id). This
|
||||
executing processes by owner and PID (process ID). This
|
||||
is usually invoked with <option>ax</option> options,
|
||||
and may be piped to <link linkend="grepref">grep</link>
|
||||
or <link linkend="sedref">sed</link> to search for a
|
||||
|
@ -16632,12 +16663,12 @@ exit 0
|
|||
<secondary>process id</secondary>
|
||||
</indexterm>
|
||||
<listitem>
|
||||
<para>Identifies <emphasis>process id (pid)</emphasis> of a
|
||||
<para>Identifies <emphasis>process ID (PID)</emphasis> of a
|
||||
running job. Since job control commands, such as <link
|
||||
linkend="killref">kill</link> and <command>renice</command>
|
||||
act on the <emphasis>pid</emphasis> of a process (not
|
||||
act on the <emphasis>PID</emphasis> of a process (not
|
||||
its name), it is sometimes necessary to identify that
|
||||
<emphasis>pid</emphasis>. The <command>pidof</command>
|
||||
<emphasis>PID</emphasis>. The <command>pidof</command>
|
||||
command is the approximate counterpart to the <link
|
||||
linkend="ppidref">$PPID</link> internal variable.</para>
|
||||
|
||||
|
@ -16665,7 +16696,7 @@ exit 0
|
|||
<secondary>fuser</secondary>
|
||||
</indexterm>
|
||||
<listitem>
|
||||
<para>Identifies the processes (by pid) that are accessing
|
||||
<para>Identifies the processes (by PID) that are accessing
|
||||
a given file, set of files, or directory. May also be
|
||||
invoked with the <option>-k</option> option, which kills
|
||||
those processes. This has interesting implications for
|
||||
|
@ -17552,8 +17583,10 @@ then
|
|||
|
||||
<para>
|
||||
<programlisting>#!/bin/bash
|
||||
# This script is for illustrative purposes only.
|
||||
# Run it at your own peril -- it *will* freeze your system.
|
||||
|
||||
while 1 # Endless loop.
|
||||
while true # Endless loop.
|
||||
do
|
||||
$0 & # This script invokes itself . . .
|
||||
#+ forks an infinite number of times . . .
|
||||
|
@ -17620,7 +17653,7 @@ exit 0 # Will not exit here, because this script will never terminate.</pr
|
|||
<para>Get info about or make changes to root device, swap space, or video
|
||||
mode. The functionality of <command>rdev</command> has generally been taken over by
|
||||
<command>lilo</command>, but <command>rdev</command> remains
|
||||
useful for setting up a ram disk. This is another dangerous command, if misused.
|
||||
useful for setting up a ram disk. This is a dangerous command, if misused.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -17957,6 +17990,10 @@ echo $textfile_listing2
|
|||
# Thanks, S.C.</programlisting>
|
||||
</para>
|
||||
|
||||
<note><para>Command substitution invokes a <link
|
||||
linkend="subshellsref">subshell</link>.</para></note>
|
||||
|
||||
|
||||
|
||||
<caution><para>Command substitution may result in word splitting.
|
||||
<programlisting>COMMAND `echo a b` # 2 args: a and b
|
||||
|
@ -18043,13 +18080,12 @@ echo "$dir_listing" # quoted
|
|||
linkend="catref">cat</link> command.</para>
|
||||
|
||||
<para>
|
||||
<programlisting>variable1=`<file1` # Set "variable1" to contents of "file1".
|
||||
variable2=`cat file2` # Set "variable2" to contents of "file2".
|
||||
<programlisting>variable1=`<file1` # Set "variable1" to contents of "file1".
|
||||
variable2=`cat file2` # Set "variable2" to contents of "file2".
|
||||
# This, however, forks a new process,
|
||||
#+ so the line of code executes slower than the above version.
|
||||
|
||||
# Note 1:
|
||||
# Removes newlines.
|
||||
#
|
||||
# Note 2:
|
||||
# Note:
|
||||
# The variables may contain embedded whitespace,
|
||||
#+ or even (horrors), control characters.</programlisting>
|
||||
</para>
|
||||
|
@ -18159,7 +18195,6 @@ File_contents1=$(cat $file1)
|
|||
File_contents2=$(<$file2) # Bash permits this also.</programlisting></para></note>
|
||||
|
||||
|
||||
|
||||
<para>Examples of command substitution in shell scripts:
|
||||
<orderedlist>
|
||||
<listitem><para><xref linkend="bingrep"></para></listitem>
|
||||
|
@ -19627,9 +19662,19 @@ echo a111b | gawk '/a1+b/'
|
|||
<emphasis>subshells</emphasis> let the script do
|
||||
parallel processing, in effect executing multiple subtasks
|
||||
simultaneously.</para>
|
||||
|
||||
|
||||
<sidebar>
|
||||
<para>In general, an <link linkend="externalref">external
|
||||
command</link> in a script <link linkend="forkref">forks
|
||||
off</link> a subprocess, whereas a Bash <link
|
||||
linkend="builtinref">builtin</link> does not. For this reason,
|
||||
builtins execute more quickly than their external command
|
||||
equivalents.</para>
|
||||
</sidebar>
|
||||
|
||||
<variablelist id="subshellparens">
|
||||
<title><anchor id="subshellparens1">Command List in Parentheses</title>
|
||||
<title><anchor id="subshellparens1">Command List in
|
||||
Parentheses</title>
|
||||
|
||||
<varlistentry>
|
||||
<term>( command1; command2; command3; ... )</term>
|
||||
|
@ -20733,6 +20778,14 @@ echo ${array2[2]} #
|
|||
echo ${array2[3]} # fourth element</programlisting>
|
||||
</para>
|
||||
|
||||
<para><link linkend="commandsubref">Command substitution</link> can
|
||||
construct the individual elements of an array.</para>
|
||||
|
||||
<example id="scriptarray">
|
||||
<title>Loading the contents of a script into an array</title>
|
||||
<programlisting>&scriptarray;</programlisting>
|
||||
</example>
|
||||
|
||||
<para>In an array context, some Bash <link
|
||||
linkend="builtinref">builtins</link> have a slightly altered
|
||||
meaning. For example, <link linkend="unsetref">unset</link>
|
||||
|
@ -22005,11 +22058,55 @@ exit 0</programlisting>
|
|||
<programlisting>&badread;</programlisting>
|
||||
</example>
|
||||
|
||||
<para>In fact, as Anthony Richardson points out, piping to
|
||||
<emphasis>any</emphasis> loop can cause a similar problem.</para>
|
||||
|
||||
<para>
|
||||
<programlisting># Loop piping troubles.
|
||||
# This example by Anthony Richardson.
|
||||
|
||||
|
||||
foundone=false
|
||||
find $HOME -type f -atime +30 -size 100k |
|
||||
while true
|
||||
do
|
||||
read f
|
||||
echo "$f is over 100KB and has not been accessed in over 30 days"
|
||||
echo "Consider moving the file to archives."
|
||||
foundone=true
|
||||
done
|
||||
|
||||
# foundone will always be false here since it is
|
||||
#+ set to true inside a subshell
|
||||
if [ $foundone = false ]
|
||||
then
|
||||
echo "No files need archiving."
|
||||
fi
|
||||
|
||||
# =====================Now, here is the correct way:=================
|
||||
|
||||
foundone=false
|
||||
for f in $(find $HOME -type f -atime +30 -size 100k) # No pipe here.
|
||||
do
|
||||
echo "$f is over 100KB and has not been accessed in over 30 days"
|
||||
echo "Consider moving the file to archives."
|
||||
foundone=true
|
||||
done
|
||||
|
||||
if [ $foundone = false ]
|
||||
then
|
||||
echo "No files need archiving."
|
||||
fi</programlisting>
|
||||
</para>
|
||||
|
||||
<para>--</para>
|
||||
|
||||
<para>Using <quote>suid</quote> commands within scripts is risky,
|
||||
as it may compromise system security.
|
||||
<footnote><para>Setting the <emphasis>suid</emphasis> permission on
|
||||
the script itself has no effect.</para></footnote>
|
||||
</para>
|
||||
</para>
|
||||
|
||||
|
||||
<para>Using shell scripts for CGI programming may be problematic. Shell
|
||||
script variables are not <quote>typesafe</quote>, and this can cause
|
||||
|
@ -22478,6 +22575,11 @@ test "$city" \< Paris && echo "Yes, Paris is greater than $city" # Greater ASCI
|
|||
<programlisting>&pbook;</programlisting>
|
||||
</example>
|
||||
|
||||
<example id="usrmnt">
|
||||
<title>Another (useful) script that recursively calls itself</title>
|
||||
<programlisting>&usrmnt;</programlisting>
|
||||
</example>
|
||||
|
||||
<caution><para>Too many levels of recursion can exhaust the
|
||||
script's stack space, causing a segfault.</para></caution>
|
||||
|
||||
|
@ -23337,12 +23439,13 @@ fi</programlisting>
|
|||
good book on the subject? I was looking to buy a tutorial and
|
||||
reference covering all aspects of the subject. I was looking for a
|
||||
book that would take difficult concepts, turn them inside out, and
|
||||
explain them in excruciating detail with well-commented examples.
|
||||
explain them in excruciating detail, with well-commented examples.
|
||||
<footnote><para>This is the notorious <quote>flog it to
|
||||
death</quote> technique.</para></footnote>
|
||||
In fact, I was looking for this very book, or something much
|
||||
like it. Unfortunately, it didn't exist, and if I wanted it,
|
||||
I'd have to write it. And so, here we are, folks.</para>
|
||||
In fact, I was looking for <emphasis>this very book</emphasis>,
|
||||
or something much like it. Unfortunately, it didn't exist,
|
||||
and if I wanted it, I'd have to write it. And so, here we are,
|
||||
folks.</para>
|
||||
|
||||
<para>This reminds me of the apocryphal story about the mad
|
||||
professor. Crazy as a loon, the fellow was. At the sight of a
|
||||
|
@ -23353,7 +23456,7 @@ fi</programlisting>
|
|||
write a book with the very same title. When he died some years
|
||||
later, he allegedly had several thousand books to his credit,
|
||||
probably putting even Asimov to shame. The books might not have
|
||||
been any good, who knows, but does that really matter? Here's
|
||||
been any good -- who knows -- but does that really matter? Here's
|
||||
a fellow who lived his dream, even if he was obsessed by it,
|
||||
driven by it, and I can't help admiring the old coot...</para>
|
||||
|
||||
|
@ -23373,7 +23476,7 @@ fi</programlisting>
|
|||
HOW-2 Meet Women: The Shy Man's Guide to
|
||||
Relationships</ulink>. He has also written the <ulink
|
||||
url="http://tldp.org/HOWTO/Software-Building-HOWTO.html">Software-Building
|
||||
HOWTO</ulink>.</para>
|
||||
HOWTO</ulink>. Lately, he has been trying his hand at short fiction.</para>
|
||||
|
||||
<para>A Linux user since 1995 (Slackware 2.2, kernel 1.2.1),
|
||||
the author has emitted a few
|
||||
|
@ -23543,11 +23646,11 @@ fi</programlisting>
|
|||
were Gabor Kiss, Leopold Toetsch, Peter Tillier, Marcus Berglof,
|
||||
Tony Richardson, Nick Drage (script ideas!), Rich Bartell, Jess
|
||||
Thrysoee, Adam Lazur, Bram Moolenaar, Baris Cicek, Greg Keraunen,
|
||||
Keith Matthews, Sandro Magi, Albert Reiner, Dim Segebart,
|
||||
Rory Winston, Lee Bigelow, Wayne Pollock, <quote>jipe</quote>,
|
||||
Emilio Conti, Dennis Leeuw, Dan Jacobson, Aurelio Marinho Jargas,
|
||||
Edward Scholtz, Jean Helou, and David Lawyer (himself an author
|
||||
of 4 HOWTOs).</para>
|
||||
Keith Matthews, Sandro Magi, Albert Reiner, Dim Segebart, Rory
|
||||
Winston, Lee Bigelow, Wayne Pollock, <quote>jipe,</quote> Emilio
|
||||
Conti, Dennis Leeuw, Dan Jacobson, Aurelio Marinho Jargas,
|
||||
Edward Scholtz, Jean Helou, Chris Martin, and David Lawyer
|
||||
(himself an author of 4 HOWTOs).</para>
|
||||
|
||||
<para>My gratitude to <ulink url="mailto:chet@po.cwru.edu">Chet
|
||||
Ramey</ulink> and Brian Fox for writing <command>Bash</command>,
|
||||
|
@ -24341,6 +24444,10 @@ fi</programlisting>
|
|||
<appendix id="refcards">
|
||||
<title>Reference Cards</title>
|
||||
|
||||
<para>The following reference cards provide a useful
|
||||
<emphasis>summary</emphasis> of certain scripting concepts.
|
||||
The foregoing text treats these matters in more depth and gives
|
||||
usage examples.</para>
|
||||
|
||||
<table pgwide=0>
|
||||
<title>Special Shell Variables</title>
|
||||
|
@ -24373,11 +24480,11 @@ fi</programlisting>
|
|||
<entry>Number of positional parameters</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>$*</option></entry>
|
||||
<entry>All the positional parameters (as a single word)</entry>
|
||||
<entry><option>"$*"</option></entry>
|
||||
<entry>All the positional parameters (as a single word) *</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>$@</option></entry>
|
||||
<entry><option>"$@"</option></entry>
|
||||
<entry>All the positional parameters (as separate strings)</entry>
|
||||
</row>
|
||||
<row>
|
||||
|
@ -24415,6 +24522,9 @@ fi</programlisting>
|
|||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para><command>*</command> <emphasis>Must be quoted</emphasis>,
|
||||
otherwise it defaults to
|
||||
<quote><varname>$@</varname></quote>.</para>
|
||||
|
||||
|
||||
<table>
|
||||
|
@ -24459,7 +24569,7 @@ fi</programlisting>
|
|||
<entry><option>-ne</option></entry>
|
||||
<entry>Not equal to</entry>
|
||||
<entry></entry>
|
||||
<entry><option>!</option></entry>
|
||||
<entry><option>!=</option></entry>
|
||||
<entry>Not equal to</entry>
|
||||
</row>
|
||||
<row>
|
||||
|
@ -24670,6 +24780,7 @@ fi</programlisting>
|
|||
<entry>Value of <parameter>var</parameter>, same as
|
||||
<parameter>$var</parameter></entry>
|
||||
</row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry><option>${var-DEFAULT}</option></entry>
|
||||
<entry>If <parameter>var</parameter> not set, evaluate expression
|
||||
|
@ -24677,9 +24788,11 @@ fi</programlisting>
|
|||
</row>
|
||||
<row>
|
||||
<entry><option>${var:-DEFAULT}</option></entry>
|
||||
<entry>If <parameter>var</parameter> not set, evaluate expression
|
||||
as <parameter>$DEFAULT</parameter> *</entry>
|
||||
<entry>If <parameter>var</parameter> not set or is empty,
|
||||
evaluate expression as <parameter>$DEFAULT</parameter>
|
||||
*</entry>
|
||||
</row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry><option>${var=DEFAULT}</option></entry>
|
||||
<entry>If <parameter>var</parameter> not set, evaluate expression
|
||||
|
@ -24690,6 +24803,7 @@ fi</programlisting>
|
|||
<entry>If <parameter>var</parameter> not set, evaluate expression
|
||||
as <parameter>$DEFAULT</parameter> *</entry>
|
||||
</row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry><option>${var+OTHER}</option></entry>
|
||||
<entry>If <parameter>var</parameter> set, evaluate expression as
|
||||
|
@ -24700,6 +24814,7 @@ fi</programlisting>
|
|||
<entry>If <parameter>var</parameter> set, evaluate expression as
|
||||
<parameter>$OTHER</parameter>, otherwise as null string</entry>
|
||||
</row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry><option>${var?ERR_MSG}</option></entry>
|
||||
<entry>If <parameter>var</parameter> not set, print
|
||||
|
@ -24710,6 +24825,17 @@ fi</programlisting>
|
|||
<entry>If <parameter>var</parameter> not set, print
|
||||
<parameter>$ERR_MSG</parameter> *</entry>
|
||||
</row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry><option>${!varprefix*}</option></entry>
|
||||
<entry>Matches all previously declared variables beginning with
|
||||
<parameter>varprefix</parameter></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>${!varprefix@}</option></entry>
|
||||
<entry>Matches all previously declared variables beginning with
|
||||
<parameter>varprefix</parameter></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
@ -24735,12 +24861,12 @@ fi</programlisting>
|
|||
</row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry><option>{$string:position}</option></entry>
|
||||
<entry><option>${string:position}</option></entry>
|
||||
<entry>Extract substring from <parameter>$string</parameter>
|
||||
at <parameter>$position</parameter></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>{$string:position:length}</option></entry>
|
||||
<entry><option>${string:position:length}</option></entry>
|
||||
<entry>Extract <parameter>$length</parameter>
|
||||
characters substring from <parameter>$string</parameter>
|
||||
at <parameter>$position</parameter></entry>
|
||||
|
@ -24856,6 +24982,120 @@ fi</programlisting>
|
|||
<emphasis>regular expression</emphasis>.</para>
|
||||
|
||||
|
||||
|
||||
<table pgwide=0>
|
||||
<title>Miscellaneous Constructs</title>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
|
||||
<row>
|
||||
<entry>Expression</entry>
|
||||
<entry>Interpretation</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry>Brackets</entry><entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>if [ CONDITION ]</option></entry>
|
||||
<entry>Test construct</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>if [[ CONDITION ]]</option></entry>
|
||||
<entry>Extended test construct</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>Array[1]=element1</option></entry>
|
||||
<entry>Array initialization</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option> [a-z]</option></entry>
|
||||
<entry>Range of characters within a Regular Expression</entry>
|
||||
</row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry>Curly Brackets</entry><entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>${variable}</option></entry>
|
||||
<entry>Parameter substitution</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>${!variable}</option></entry>
|
||||
<entry>Indirect variable reference</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>{ command1; command2 }</option></entry>
|
||||
<entry>Block of code</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>{string1,string2,string3,...}</option></entry>
|
||||
<entry>Brace expansion</entry>
|
||||
</row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry>Parentheses</entry><entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>( command1; command2 )</option></entry>
|
||||
<entry>Command group executed within a subshell</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>Array=(element1 element2 element3)</option></entry>
|
||||
<entry>Array initialization</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>result=$(COMMAND)</option></entry>
|
||||
<entry>Execute command in subshell and assign result to
|
||||
variable</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>>(COMMAND)</option></entry>
|
||||
<entry>Process substitution</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option><(COMMAND)</option></entry>
|
||||
<entry>Process substitution</entry>
|
||||
</row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry>Double Parentheses</entry><entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>(( var = 78 ))</option></entry>
|
||||
<entry>Integer arithmetic</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>var=$(( 20 + 5 ))</option></entry>
|
||||
<entry>Integer arithmetic, with variable assignment</entry>
|
||||
</row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry>Quoting</entry><entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>"$variable"</option></entry>
|
||||
<entry>"Weak" quoting</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>'string'</option></entry>
|
||||
<entry>"Strong" quoting</entry>
|
||||
</row>
|
||||
<row><entry></entry><entry></entry></row>
|
||||
<row>
|
||||
<entry>Back Quotes</entry><entry></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><option>result=`COMMAND`</option></entry>
|
||||
<entry>Execute command in subshell and assign result to variable</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
</appendix>
|
||||
<!-- Reference Cards appendix -->
|
||||
|
||||
|
@ -26484,6 +26724,20 @@ Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>Monitoring Processes</command></term>
|
||||
<listitem>
|
||||
<para>Write a script to continually monitor all running
|
||||
processes and to keep track of how many child processes each
|
||||
parent spawns. If a process spawns more than five children,
|
||||
then the script sends an e-mail to the system administrator
|
||||
(or root) with all relevant information, including the
|
||||
time, PID of the parent, PIDs of the children, etc. The
|
||||
script writes a report to a log file every ten minutes.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>Strip Comments</command></term>
|
||||
<listitem>
|
||||
|
@ -26886,6 +27140,7 @@ B. Distribution of the work or derivative of the work in any standard
|
|||
<para>Linux is a trademark registered to Linus Torvalds.</para>
|
||||
<para>Unix and UNIX are trademarks registered to the Open Group.</para>
|
||||
<para>MS Windows is a trademark registered to the Microsoft Corp.</para>
|
||||
<para>Scrabble is a trademark registered to Hasbro, Inc.</para>
|
||||
<para>All other commercial trademarks mentioned in the body of this work
|
||||
are registered to their respective owners.</para>
|
||||
</sidebar>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# arglist.sh
|
||||
# Invoke this script with several arguments, such as "one two three".
|
||||
|
||||
E_BADARGS=65
|
||||
|
@ -35,4 +36,12 @@ echo "Arg list seen as separate words."
|
|||
|
||||
echo
|
||||
|
||||
echo "Listing args with \$* (unquoted):"
|
||||
for arg in $*
|
||||
do
|
||||
echo "Arg #$index = $arg"
|
||||
let "index+=1"
|
||||
done # Unquoted $* sees arguments as separate words.
|
||||
echo "Arg list seen as separate words."
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -5,8 +5,8 @@ echo -n "What is your favorite vegetable? "
|
|||
read
|
||||
|
||||
echo "Your favorite vegetable is $REPLY."
|
||||
# REPLY holds the value of last "read" if and only if
|
||||
# no variable supplied.
|
||||
# REPLY holds the value of last "read" if and only if
|
||||
#+ no variable supplied.
|
||||
|
||||
echo
|
||||
echo -n "What is your favorite fruit? "
|
||||
|
@ -14,8 +14,8 @@ read fruit
|
|||
echo "Your favorite fruit is $fruit."
|
||||
echo "but..."
|
||||
echo "Value of \$REPLY is still $REPLY."
|
||||
# $REPLY is still set to its previous value because
|
||||
# the variable $fruit absorbed the new "read" value.
|
||||
# $REPLY is still set to its previous value because
|
||||
#+ the variable $fruit absorbed the new "read" value.
|
||||
|
||||
echo
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#!/bin/bash
|
||||
# t-out.sh (per a suggestion by "syngin seven)
|
||||
# t-out.sh
|
||||
# Inspired by a suggestion from "syngin seven" (thanks).
|
||||
|
||||
TIMELIMIT=4 # 4 seconds
|
||||
|
||||
TIMELIMIT=4 # 4 seconds
|
||||
|
||||
read -t $TIMELIMIT variable <&1
|
||||
|
||||
|
@ -15,3 +17,8 @@ else
|
|||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# Exercise for the reader:
|
||||
# -----------------------
|
||||
# Why is the redirection (<&1) necessary in line 8?
|
||||
# What happens if it is omitted?
|
||||
|
|
Loading…
Reference in New Issue