mirror of https://github.com/tLDP/LDP
updated
This commit is contained in:
parent
738864a37c
commit
1023b2f15b
|
@ -3,6 +3,80 @@ RELEASE HISTORY
|
|||
Change log
|
||||
|
||||
|
||||
Version 1.8 [Cleanups & revisions]
|
||||
Working toward 'BREADFRUIT' release
|
||||
|
||||
|
||||
1) Revised "self-document.sh" to remove unnecessary 'cat.'
|
||||
|
||||
2) In "cvt.sh" example, quoted target file name and added exercise.
|
||||
|
||||
3) Updated Jordi Sanfeliu's e-mail address in "Credits" chapter and in
|
||||
"tree.sh" example script.
|
||||
|
||||
4) In "blot-out.sh" script, updated the Peter Gutmann URL.
|
||||
|
||||
5) In "Miscellaneous" subsection of "System and Administrative Commands"
|
||||
chapter"
|
||||
Added "watch" command.
|
||||
|
||||
6) In the introduction, in reason not to use shell scripts,
|
||||
Removed misleading reference to Open Source (thank you, Peter Lietz, for
|
||||
pointing this out).
|
||||
|
||||
7) In "Quoting" chapter:
|
||||
Added footnote about problem double quoting "!" and "\!".
|
||||
(Thanks, Wayne Pollock.)
|
||||
|
||||
8) In "Internal Commands" chapter:
|
||||
Added caution about 'cd //' problem. (Thanks, Wayne Pollock.)
|
||||
Added short example of "$!" usage. (Thanks, Jacques Lederer.)
|
||||
|
||||
9) In "Arrays" chapter:
|
||||
Replaced "empty-array.sh" with an extended version.
|
||||
Added note that Bash treats variables as arrays, even if not declared as
|
||||
such.
|
||||
Added example of nested arrays.
|
||||
Added example of copying and concatenating arrays.
|
||||
(All the above thanks to Michael Zick.)
|
||||
|
||||
10) In "Tests" chapter:
|
||||
Fixed up "Tests Constructs" section link (finally!).
|
||||
|
||||
11) In "Command Substitution" chapter:
|
||||
Added mention of $(<$file) construct.
|
||||
|
||||
12) In "Functions" chapter:
|
||||
Added material to nested functions in-line examples.
|
||||
|
||||
13) In the "Portability Issues" section of the "Miscellany" chapter:
|
||||
Added short list of Bash-specific features.
|
||||
|
||||
14) In "File and Archiving Commands" section of "External Commands" Chapter:
|
||||
Added "dos2unix" utility.
|
||||
|
||||
15) In "Gotchas" chapter:
|
||||
Added short in-line example of using an uninitialized variable.
|
||||
Added in-line example showing DOS-formatted script failing to run.
|
||||
|
||||
16) In "Contributed Scripts" appendix:
|
||||
Added Michael Zick's "directory-info.sh" script.
|
||||
|
||||
17) In "Bibliography" section:
|
||||
Updated "The UNIX CD Bookshelf" reference.
|
||||
Added Eric Pement's sed resources page.
|
||||
Removed outdated "Sed F.A.Q." reference.
|
||||
Updated Frisch entry.
|
||||
Updated Shelldorado and Giles Orr entries.
|
||||
|
||||
18) Updated sample .bashrc file (Appendix G).
|
||||
|
||||
19) A few minor error corrections and clean ups at various places in the
|
||||
text.
|
||||
|
||||
|
||||
|
||||
|
||||
Version 1.7 (minor update)
|
||||
'COCONUT' release
|
||||
01/05/03
|
||||
|
|
|
@ -17,6 +17,8 @@ read-r.sh
|
|||
rnd.sh
|
||||
rot13.sh
|
||||
here-function.sh
|
||||
directory-info.sh (lines 273 and 353)
|
||||
bashrc (comments on lines 596 and 618)
|
||||
|
||||
have the "<" and ">" in place of angle brackets (< and >), or & in
|
||||
place of the ampersand (&). This is necessary for the Docbook SGML
|
||||
|
|
|
@ -268,6 +268,8 @@ Uncomment line below to generate index.
|
|||
<!ENTITY brokenlink SYSTEM "broken-link.sh">
|
||||
<!ENTITY continuenex SYSTEM "continue-n.example">
|
||||
<!ENTITY pickcard SYSTEM "pick-card.sh">
|
||||
<!ENTITY copyarray SYSTEM "CopyArray.sh">
|
||||
<!ENTITY directoryinfo SYSTEM "directory-info.sh">
|
||||
<!ENTITY evalex SYSTEM "eval.example">
|
||||
<!ENTITY namesdata SYSTEM "names.data">
|
||||
<!ENTITY gen0data SYSTEM "gen0">
|
||||
|
@ -277,20 +279,20 @@ Uncomment line below to generate index.
|
|||
<book>
|
||||
<bookinfo>
|
||||
<title>Advanced Bash-Scripting Guide</title>
|
||||
<subtitle>An in-depth exploration of the gentle art of shell scripting</subtitle>
|
||||
<subtitle>An in-depth exploration of the art of shell scripting</subtitle>
|
||||
|
||||
|
||||
<author>
|
||||
<firstname>Mendel</firstname>
|
||||
<surname>Cooper</surname>
|
||||
<affiliation>
|
||||
<orgname>Brindle-Phlogiston Associates</orgname>
|
||||
<orgname></orgname>
|
||||
<address><email>thegrendel@theriver.com</email></address>
|
||||
</affiliation>
|
||||
</author>
|
||||
|
||||
<releaseinfo>1.7</releaseinfo>
|
||||
<pubdate>05 January 2003</pubdate>
|
||||
<releaseinfo>1.8</releaseinfo>
|
||||
<pubdate>10 May 2003</pubdate>
|
||||
|
||||
|
||||
<revhistory>
|
||||
|
@ -395,6 +397,14 @@ Uncomment line below to generate index.
|
|||
more script.</revremark>
|
||||
</revision>
|
||||
|
||||
<revision>
|
||||
<revnumber>1.8</revnumber>
|
||||
<date>10 May 2003</date>
|
||||
<authorinitials>mc</authorinitials>
|
||||
<revremark>'BREADFRUIT' release: a number of bugfixes, more scripts
|
||||
and material.</revremark>
|
||||
</revision>
|
||||
|
||||
</revhistory>
|
||||
|
||||
|
||||
|
@ -402,7 +412,7 @@ Uncomment line below to generate index.
|
|||
|
||||
<para>This tutorial assumes no previous knowledge of
|
||||
scripting or programming, but progresses rapidly toward an
|
||||
intermediate/advanced level of instruction <emphasis>...all
|
||||
intermediate/advanced level of instruction <emphasis>. . . all
|
||||
the while sneaking in little snippets of UNIX wisdom and
|
||||
lore</emphasis>. It serves as a textbook, a manual for
|
||||
self-study, and a reference and source of knowledge on shell
|
||||
|
@ -415,7 +425,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-1.7.tar.bz2">
|
||||
url="http://personal.riverusers.com/~thegrendel/abs-guide-1.8.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>
|
||||
|
@ -456,7 +466,7 @@ Uncomment line below to generate index.
|
|||
|
||||
|
||||
<para>A working knowledge of shell scripting is essential to anyone
|
||||
wishing to become reasonably adept at system administration,
|
||||
wishing to become reasonably proficient at system administration,
|
||||
even if they do not anticipate ever having to actually write a
|
||||
script. Consider that as a Linux machine boots up, it executes the
|
||||
shell scripts in <filename class="directory">/etc/rc.d</filename>
|
||||
|
@ -510,7 +520,7 @@ Uncomment line below to generate index.
|
|||
<para>cross-platform portability required (use C instead)</para>
|
||||
</listitem> <listitem>
|
||||
<para>complex applications, where structured programming is
|
||||
a necessity (need typechecking of variables, function
|
||||
a necessity (need type-checking of variables, function
|
||||
prototypes, etc.)</para>
|
||||
</listitem> <listitem>
|
||||
<para>mission-critical applications upon which you are betting the
|
||||
|
@ -539,8 +549,9 @@ Uncomment line below to generate index.
|
|||
</listitem> <listitem>
|
||||
<para>need to use libraries or interface with legacy code</para>
|
||||
</listitem> <listitem>
|
||||
<para>proprietary, closed-source applications (shell scripts are
|
||||
necessarily Open Source)</para>
|
||||
<para>proprietary, closed-source applications (shell scripts put the
|
||||
source code right out in the open for all the world to see)</para>
|
||||
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
|
||||
|
@ -562,19 +573,19 @@ Uncomment line below to generate index.
|
|||
and even a few from the updated <emphasis>ksh93</emphasis>
|
||||
have been merged into Bash.</para></footnote>
|
||||
|
||||
and the C Shell and its variants. (Note that C Shell programming
|
||||
and the C Shell and its variants. (Note that C Shell programming
|
||||
is not recommended due to certain inherent problems, as pointed out
|
||||
in an October, 1993 <ulink
|
||||
url="http://www.etext.org/Quartz/computer/unix/csh.harmful.gz">Usenet
|
||||
post</ulink> by Tom Christiansen).
|
||||
post</ulink> by Tom Christiansen.)
|
||||
</para>
|
||||
|
||||
<para>What follows is a tutorial on shell scripting. It relies
|
||||
heavily on examples to illustrate various features of the shell.
|
||||
As far as possible, the example scripts have been tested,
|
||||
and some of them may even be useful in real life. The
|
||||
reader should use the actual examples in the source archive
|
||||
(<filename>something-or-other.sh</filename>),
|
||||
The example scripts work -- they've been tested -- and some
|
||||
of them are even useful in real life. The reader can play with
|
||||
the actual working code of the examples in the source archive
|
||||
(<filename>scriptname.sh</filename>),
|
||||
|
||||
<footnote><para>By convention, user-written shell scripts that are
|
||||
Bourne shell compliant generally take a name with a
|
||||
|
@ -585,13 +596,13 @@ Uncomment line below to generate index.
|
|||
give them execute permission (<userinput>chmod u+rx
|
||||
scriptname</userinput>), then run them to see what happens.
|
||||
Should the source archive not be available, then cut-and-paste from
|
||||
the HTML, pdf, or text rendered versions. Be aware that some of
|
||||
the HTML, pdf, or text rendered versions. Be aware that some of
|
||||
the scripts below introduce features before they are explained,
|
||||
and this may require the reader to temporarily skip ahead for
|
||||
enlightenment.</para>
|
||||
|
||||
<para>Unless otherwise noted, the book author wrote the example
|
||||
scripts that follow.</para>
|
||||
<para>Unless otherwise noted, the author of this book wrote the
|
||||
example scripts that follow.</para>
|
||||
|
||||
</chapter> <!-- Why Shell Programming? -->
|
||||
|
||||
|
@ -906,9 +917,9 @@ fi</programlisting>
|
|||
<note><para>Of course, an escaped <token>#</token> in an
|
||||
<command>echo</command> statement does
|
||||
<emphasis>not</emphasis> begin a comment. Likewise, a
|
||||
<token>#</token> appears in <link linkend="psub2">certain
|
||||
parameter substitution constructs</link> and in <link
|
||||
linkend="numconstants">numerical constant expressions</link>.
|
||||
<token>#</token> appears in <link linkend="psub2">certain parameter
|
||||
substitution constructs</link> and in <link linkend="numconstants">
|
||||
numerical constant expressions</link>.
|
||||
|
||||
<programlisting>echo "The # here does not begin a comment."
|
||||
echo 'The # here does not begin a comment.'
|
||||
|
@ -2884,6 +2895,7 @@ arch=$(uname -m)</programlisting></para>
|
|||
<sect1 id="untyped">
|
||||
<title>Bash Variables Are Untyped</title>
|
||||
|
||||
<para><anchor id="bvuntyped"></para>
|
||||
<para>Unlike many other programming languages, Bash does not segregate
|
||||
its variables by <quote>type</quote>. Essentially, Bash
|
||||
variables are character strings, but, depending on context, Bash
|
||||
|
@ -2946,10 +2958,11 @@ arch=$(uname -m)</programlisting></para>
|
|||
any other process.</para>
|
||||
|
||||
<para>Every time a shell starts, it creates shell variables that
|
||||
correspond to its own environmental variables. Updating or
|
||||
adding new shell variables causes the shell to update its
|
||||
environment, and all the shell's child processes (the commands
|
||||
it executes) inherit this environment.</para>
|
||||
correspond to its own environmental variables. Updating
|
||||
or adding new environmental variables causes the shell
|
||||
to update its environment, and all the shell's child
|
||||
processes (the commands it executes) inherit this
|
||||
environment.</para>
|
||||
|
||||
</note>
|
||||
|
||||
|
@ -3185,8 +3198,45 @@ fi
|
|||
enclose it in double quotes (<token>" "</token>). This
|
||||
preserves all special characters within the variable name,
|
||||
except <token>$</token>, <token>`</token> (backquote),
|
||||
and <token>\</token> (escape). Keeping <token>$</token>
|
||||
as a special character permits referencing a quoted variable
|
||||
and <token>\</token> (escape).
|
||||
|
||||
<footnote>
|
||||
|
||||
<para>Encapsulating <quote>!</quote> within double
|
||||
quotes gives an error when used <emphasis>from the command
|
||||
line</emphasis>. Apparently this is interpreted as a <link
|
||||
linkend="histcommands">history command</link>. Within a script,
|
||||
though, this problem does not occur.</para>
|
||||
|
||||
<para>Of more concern is the inconsistent behavior of
|
||||
<quote>\</quote> within double quotes.
|
||||
|
||||
<screen>
|
||||
<prompt>bash$ </prompt><userinput>echo hello\!</userinput>
|
||||
<computeroutput>hello!</computeroutput>
|
||||
|
||||
|
||||
<prompt>bash$ </prompt><userinput>echo "hello\!"</userinput>
|
||||
<computeroutput>hello\!</computeroutput>
|
||||
|
||||
|
||||
|
||||
|
||||
<prompt>bash$ </prompt><userinput>echo -e x\ty</userinput>
|
||||
<computeroutput>xty</computeroutput>
|
||||
|
||||
|
||||
<prompt>bash$ </prompt><userinput>echo -e "x\ty"</userinput>
|
||||
<computeroutput>x y</computeroutput>
|
||||
</screen>
|
||||
|
||||
(Thank you, Wayne Pollock, for pointing this out.)
|
||||
</para>
|
||||
|
||||
</footnote>
|
||||
|
||||
Keeping <token>$</token> as a special character within
|
||||
double quotes permits referencing a quoted variable
|
||||
(<replaceable>"$variable"</replaceable>), that is, replacing the
|
||||
variable with its value (see <xref linkend="ex9">, above).</para>
|
||||
|
||||
|
@ -3750,7 +3800,9 @@ echo "exit status of \"! true\" = $?" # 1
|
|||
<command>if/then</command> construct.</para>
|
||||
|
||||
<sect1 id="testconstructs">
|
||||
<title><anchor id="testconstructs1">Test Constructs</title>
|
||||
<title>Test Constructs</title>
|
||||
|
||||
<para><anchor id="testconstructs1"></para>
|
||||
|
||||
<itemizedlist id="testingref">
|
||||
|
||||
|
@ -3993,8 +4045,8 @@ fi</programlisting>
|
|||
</indexterm>
|
||||
|
||||
<para><anchor id="dblbrackets">The <token>[[ ]]</token> construct
|
||||
is the shell equivalent of <token>[ ]</token>. This is the
|
||||
<emphasis>extended test command</emphasis>, adopted from
|
||||
is the more versatile Bash version of <token>[ ]</token>. This
|
||||
is the <emphasis>extended test command</emphasis>, adopted from
|
||||
<emphasis>ksh88</emphasis>.</para>
|
||||
|
||||
<note><para>No filename expansion or word splitting takes place
|
||||
|
@ -6468,7 +6520,28 @@ echo "$@" # 3 4 5
|
|||
<secondary>last job background</secondary>
|
||||
</indexterm>
|
||||
<listitem>
|
||||
|
||||
<para>PID (process id) of last job run in background</para>
|
||||
|
||||
<para>
|
||||
<programlisting>LOG=$0.log
|
||||
|
||||
COMMAND1="sleep 100"
|
||||
|
||||
echo "Logging PIDs background commands for script: $0" >> "$LOG"
|
||||
# So they can be monitored, and killed as necessary.
|
||||
echo >> "$LOG"
|
||||
|
||||
# Logging commands.
|
||||
|
||||
echo -n "PID of \"$COMMAND1\": " >> "$LOG"
|
||||
${COMMAND1} &
|
||||
echo $! >> "$LOG"
|
||||
# PID of "sleep 100": 1506
|
||||
|
||||
# Thank you, Jacques Lederer, for suggesting this.</programlisting>
|
||||
</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -8791,6 +8864,19 @@ done</programlisting></para>
|
|||
linkend="oldpwd">$OLDPWD</link>, the previous working
|
||||
directory.</para>
|
||||
|
||||
<para><anchor id="doubleslashref"></para>
|
||||
|
||||
<caution><para>The <command>cd</command> command does not function
|
||||
as expected when presented with two forward slashes.
|
||||
|
||||
<screen>
|
||||
<prompt>bash$ </prompt><userinput>cd //</userinput>
|
||||
<prompt>bash$ </prompt><userinput>pwd</userinput>
|
||||
<computeroutput>//</computeroutput>
|
||||
</screen>
|
||||
The output should, of course, be <computeroutput>/</computeroutput>.
|
||||
This is a problem both from the command line and in a script.</para></caution>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -10914,11 +11000,17 @@ find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \
|
|||
<programlisting>sleep 3
|
||||
# Pauses 3 seconds.</programlisting>
|
||||
</para>
|
||||
|
||||
<note><para>The <command>sleep</command> command defaults to
|
||||
seconds, but minute, hours, or days may also be specified.
|
||||
<programlisting>sleep 3 h
|
||||
# Pauses 3 hours!</programlisting>
|
||||
</para></note>
|
||||
|
||||
<note><para>The <link linkend="watchref">watch</link> command may
|
||||
be a better choice than <command>sleep</command> for running
|
||||
commands at timed intervals.</para></note>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -13142,6 +13234,9 @@ gzip -cd patchXX.gz | patch -p0
|
|||
<programlisting>&fileintegrity;</programlisting>
|
||||
</example>
|
||||
|
||||
<para>See also <xref linkend="directoryinfo"> for a creative use of
|
||||
the <command>md5sum</command> command.</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -13348,6 +13443,23 @@ echo "tempfile name = $tempfile"
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>dos2unix</command></term>
|
||||
<indexterm>
|
||||
<primary>dos2unix</primary>
|
||||
</indexterm>
|
||||
<indexterm>
|
||||
<primary>command</primary>
|
||||
<secondary>file converter</secondary>
|
||||
</indexterm>
|
||||
<listitem>
|
||||
<para>This utility, written by Benjamin Lin and collaborators,
|
||||
converts DOS-formatted text files (lines terminated by
|
||||
CR-LF) to UNIX format (lines terminated by LF only),
|
||||
and vice-versa.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>ptx</command></term>
|
||||
<indexterm>
|
||||
|
@ -17609,6 +17721,24 @@ print "even when I don't know where to find Perl.\n";
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><anchor id="watchref"><command>watch</command></term>
|
||||
<indexterm>
|
||||
<primary>watch</primary>
|
||||
</indexterm>
|
||||
<indexterm>
|
||||
<primary>command</primary>
|
||||
<secondary>periodic</secondary>
|
||||
</indexterm>
|
||||
<listitem>
|
||||
<para>Run a command repeatedly, at specified time intervals.</para>
|
||||
<para>The default is two-second intervals, but this may be changed
|
||||
with the <option>-n</option> option.</para>
|
||||
<para><programlisting>watch -n 5 tail /var/log/messages
|
||||
# Shows tail end of system log, /var/log/messages, every five seconds.</programlisting></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>strip</command></term>
|
||||
<indexterm>
|
||||
|
@ -17849,7 +17979,11 @@ echo "$dir_listing" # quoted
|
|||
<programlisting>variable1=`<file1` # Set "variable1" to contents of "file1".
|
||||
variable2=`cat file2` # Set "variable2" to contents of "file2".
|
||||
|
||||
# Be aware that the variables may contain embedded whitespace,
|
||||
# Note 1:
|
||||
# Removes newlines.
|
||||
#
|
||||
# Note 2:
|
||||
# The variables may contain embedded whitespace,
|
||||
#+ or even (horrors), control characters.</programlisting>
|
||||
</para>
|
||||
|
||||
|
@ -17951,8 +18085,11 @@ echo $greeting</programlisting>
|
|||
|
||||
<note><para>The <command>$(COMMAND)</command> form has
|
||||
superseded backticks for command substitution.
|
||||
<programlisting>output=$(sed -n /"$1"/p $file)
|
||||
# From "grp.sh" example.</programlisting></para></note>
|
||||
<programlisting>output=$(sed -n /"$1"/p $file) # From "grp.sh" example.
|
||||
|
||||
# Setting a variable to the contents of a text file.
|
||||
File_contents1=$(cat $file1)
|
||||
File_contents2=$(<$file2) # Bash permits this also.</programlisting></para></note>
|
||||
|
||||
|
||||
|
||||
|
@ -18003,7 +18140,7 @@ echo $greeting</programlisting>
|
|||
</indexterm> <indexterm>
|
||||
<primary>arithmetic</primary> <secondary>expansion</secondary>
|
||||
</indexterm> <listitem>
|
||||
<para><programlisting>z=`expr $z + 3` # 'expr' does the expansion.</programlisting></para>
|
||||
<para><programlisting>z=`expr $z + 3` # The 'expr' command performs the expansion.</programlisting></para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -18026,12 +18163,13 @@ echo $greeting</programlisting>
|
|||
convenient <command>let</command> construction.
|
||||
|
||||
<programlisting>z=$(($z+3))
|
||||
# $((EXPRESSION)) is arithmetic expansion. # Not to be confused with
|
||||
# command substitution.
|
||||
# $((EXPRESSION)) is arithmetic expansion. # Not to be confused with
|
||||
#+ command substitution.
|
||||
|
||||
let z=z+3
|
||||
let "z += 3" #If quotes, then spaces and special operators allowed.
|
||||
# 'let' is actually arithmetic evaluation, rather than expansion.</programlisting>
|
||||
let "z += 3" # Quotes permit the use of spaces and special operators.
|
||||
# The 'let' operator actually performs arithmetic evaluation,
|
||||
#+ rather than expansion.</programlisting>
|
||||
|
||||
All the above are equivalent. You may use whichever one
|
||||
<quote>rings your chimes</quote>.
|
||||
|
@ -19767,9 +19905,12 @@ route -n |
|
|||
<para>The function definition must precede the first call to
|
||||
it. There is no method of <quote>declaring</quote> the function,
|
||||
as, for example, in C.
|
||||
<programlisting># f1
|
||||
<programlisting>f1
|
||||
# Will give an error message, since function "f1" not yet defined.
|
||||
|
||||
declare -f f1 # This doesn't help either.
|
||||
f1 # Still an error message.
|
||||
|
||||
# However...
|
||||
|
||||
|
||||
|
@ -19784,11 +19925,11 @@ f2 ()
|
|||
echo "Function \"f2\"."
|
||||
}
|
||||
|
||||
f1 # Function "f2" is not actually called until this point,
|
||||
# although it is referenced before its definition.
|
||||
# This is permissable.
|
||||
f1 # Function "f2" is not actually called until this point,
|
||||
#+ although it is referenced before its definition.
|
||||
# This is permissable.
|
||||
|
||||
# Thanks, S.C.</programlisting>
|
||||
# Thanks, S.C.</programlisting>
|
||||
</para>
|
||||
|
||||
<para>It is even possible to nest a function within another function,
|
||||
|
@ -19803,14 +19944,16 @@ f1 # Function "f2" is not actually called until this point,
|
|||
|
||||
}
|
||||
|
||||
# f2
|
||||
# Gives an error message.
|
||||
f2 # Gives an error message.
|
||||
# Even a preceding "declare -f f2" wouldn't help.
|
||||
|
||||
f1 # Does nothing, since calling "f1" does not automatically call "f2".
|
||||
f2 # Now, it's all right to call "f2",
|
||||
# since its definition has been made visible by calling "f1".
|
||||
echo
|
||||
|
||||
# Thanks, S.C.</programlisting>
|
||||
f1 # Does nothing, since calling "f1" does not automatically call "f2".
|
||||
f2 # Now, it's all right to call "f2",
|
||||
#+ since its definition has been made visible by calling "f1".
|
||||
|
||||
# Thanks, S.C.</programlisting>
|
||||
</para>
|
||||
|
||||
<para>Function declarations can appear in unlikely places, even where a
|
||||
|
@ -20419,6 +20562,25 @@ false && ( true || echo false ) # (nothing echoed)
|
|||
<programlisting>&ex66;</programlisting>
|
||||
</example>
|
||||
|
||||
|
||||
<note><para>Bash permits array operations on variables, even if
|
||||
the variables are not explicitly declared as arrays.
|
||||
<programlisting>string=abcABC123ABCabc
|
||||
echo ${string[@]} # abcABC123ABCabc
|
||||
echo ${string[*]} # abcABC123ABCabc
|
||||
echo ${string[0]} # abcABC123ABCabc
|
||||
echo ${string[1]} # No output!
|
||||
# Why?
|
||||
echo ${#string[@]} # 1
|
||||
# One element in the array.
|
||||
# The string itself.
|
||||
|
||||
# Thank you, Michael Zick, for pointing this out.</programlisting>
|
||||
Once again this demonstrates that <link linkend="bvuntyped">Bash
|
||||
variables are untyped</link>.
|
||||
</para></note>
|
||||
|
||||
|
||||
<example id="poem">
|
||||
<title>Formatting a poem</title>
|
||||
<programlisting>&poem;</programlisting>
|
||||
|
@ -20522,7 +20684,15 @@ element_count=${#array1[*]}
|
|||
echo $element_count # 8</programlisting>
|
||||
</para>
|
||||
</tip>
|
||||
|
||||
<para>Clever scripting makes it possible to add array operations.</para>
|
||||
|
||||
<example id="copyarray">
|
||||
<title>Copying and concatenating arrays</title>
|
||||
<programlisting>©array;</programlisting>
|
||||
</example>
|
||||
|
||||
<para>--</para>
|
||||
|
||||
<para>Arrays permit deploying old familiar algorithms as shell scripts.
|
||||
Whether this is necessarily a good idea is left to the reader to
|
||||
|
@ -20536,6 +20706,28 @@ echo $element_count # 8</programlisting>
|
|||
|
||||
<para>--</para>
|
||||
|
||||
<para>Is it possible to nest arrays within arrays?</para>
|
||||
<para><programlisting>#!/bin/bash
|
||||
# Nested array.
|
||||
|
||||
# Michael Zick provided this example.
|
||||
|
||||
AnArray=( $(ls --inode --ignore-backups --almost-all \
|
||||
--directory --full-time --color=none --time=status \
|
||||
--sort=time -l ${PWD} ) ) # Commands and options.
|
||||
|
||||
# Spaces are significant . . . and don't quote anything in the above.
|
||||
|
||||
SubArray=( ${AnArray[@]:11:1} ${AnArray[@]:6:5} )
|
||||
# Array has two elements, each of which is in turn an array.
|
||||
|
||||
echo "Current directory and date of last status change:"
|
||||
echo "${SubArray[@]}"
|
||||
|
||||
exit 0</programlisting></para>
|
||||
|
||||
<para>--</para>
|
||||
|
||||
<para>Arrays enable implementing a shell script version of the <emphasis>Sieve of
|
||||
Eratosthenes</emphasis>. Of course, a resource-intensive application of this
|
||||
nature should really be written in a compiled language, such as C. It
|
||||
|
@ -21296,6 +21488,7 @@ trap 'echo "Control-C disabled."' 2
|
|||
</programlisting></para>
|
||||
|
||||
|
||||
<para><anchor id="invocationoptionsref"></para>
|
||||
<para>It is also possible to enable script options from the command
|
||||
line. Some options that will not work with
|
||||
<command>set</command> are available this way. Among these
|
||||
|
@ -21471,9 +21664,9 @@ do_something do_something
|
|||
|
||||
|
||||
<para><anchor id="wsbad">Using <link
|
||||
linkend="whitespaceref">whitespace</link> inappropriately
|
||||
(in contrast to other programming languages, Bash can be quite
|
||||
finicky about whitespace).
|
||||
linkend="whitespaceref">whitespace</link> inappropriately.
|
||||
In contrast to other programming languages, Bash can be quite
|
||||
finicky about whitespace.
|
||||
|
||||
<programlisting>var1 = 23 # 'var1=23' is correct.
|
||||
# On line above, Bash attempts to execute command "var1"
|
||||
|
@ -21486,10 +21679,18 @@ if [ $a -le 5] # if [ $a -le 5 ] is correct.
|
|||
# [[ $a -le 5 ]] also works.</programlisting>
|
||||
</para>
|
||||
|
||||
<para>Assuming uninitialized variables (variables before a value is
|
||||
<para>
|
||||
Assuming uninitialized variables (variables before a value is
|
||||
assigned to them) are <quote>zeroed out</quote>. An
|
||||
uninitialized variable has a value of <quote>null</quote>,
|
||||
<emphasis>not</emphasis> zero.</para>
|
||||
<emphasis>not</emphasis> zero.
|
||||
|
||||
<programlisting>#!/bin/bash
|
||||
|
||||
echo "uninitialized_var = $uninitialized_var"
|
||||
# uninitialized_var =</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
<para>Mixing up <emphasis>=</emphasis> and <emphasis>-eq</emphasis> in
|
||||
a test. Remember, <emphasis>=</emphasis> is for comparing literal
|
||||
|
@ -21593,11 +21794,27 @@ fi
|
|||
<command>sh</command> to <command>bash</command>, but this does
|
||||
not necessarily hold true for a generic UNIX machine.</para>
|
||||
|
||||
<para>A script with DOS-type newlines (<replaceable>\r\n</replaceable>)
|
||||
<para>
|
||||
A script with DOS-type newlines (<replaceable>\r\n</replaceable>)
|
||||
will fail to execute, since <userinput>#!/bin/bash\r\n</userinput>
|
||||
is not recognized, <emphasis>not</emphasis> the same as the
|
||||
expected <userinput>#!/bin/bash\n</userinput>. The fix is to
|
||||
convert the script to UNIX-style newlines.</para>
|
||||
convert the script to UNIX-style newlines.
|
||||
<programlisting>#!/bin/bash
|
||||
|
||||
echo "Here"
|
||||
|
||||
unix2dos $0 # Script changes itself to DOS format.
|
||||
chmod 755 $0 # Change back to execute permission.
|
||||
# The 'unix2dos' command removes execute permission.
|
||||
|
||||
./$0 # Script tries to run itself again.
|
||||
# But it won't work as a DOS file.
|
||||
|
||||
echo "There"
|
||||
|
||||
exit 0</programlisting>
|
||||
</para>
|
||||
|
||||
<para>A shell script headed by <userinput>#!/bin/sh</userinput>
|
||||
may not run in full Bash-compatibility mode. Some Bash-specific
|
||||
|
@ -21654,6 +21871,9 @@ exit 0</programlisting>
|
|||
undesirable behavior as far as CGI is concerned. Moreover, it is
|
||||
difficult to <quote>cracker-proof</quote> shell scripts.</para>
|
||||
|
||||
<para>Bash does not handle the <link linkend="doubleslashref">double slash
|
||||
(<token>//</token>) string</link> correctly.</para>
|
||||
|
||||
<para>Bash scripts written for Linux or BSD systems may need
|
||||
fixups to run on a commercial UNIX machine. Such scripts
|
||||
often employ GNU commands and filters which have greater
|
||||
|
@ -22796,12 +23016,46 @@ fi</programlisting>
|
|||
features to the latest versions of Bash.</para>
|
||||
|
||||
<para>On a commercial UNIX machine, scripts using GNU-specific
|
||||
features of standard commands may not work. This has become
|
||||
less of a problem in the last few years, as the GNU utilities
|
||||
have pretty much displaced their proprietary counterparts even
|
||||
on <quote>big-iron</quote> UNIX. Caldera's recent release of
|
||||
the source to many of the original UNIX utilities will only
|
||||
accelerate the trend.</para>
|
||||
features of standard commands may not work. This has become less
|
||||
of a problem in the last few years, as the GNU utilities have
|
||||
pretty much displaced their proprietary counterparts even on
|
||||
<quote>big-iron</quote> UNIX. Caldera's release of the source
|
||||
to many of the original UNIX utilities will only accelerate
|
||||
the trend.</para>
|
||||
|
||||
<para>Bash has certain features that the traditional Bourne shell
|
||||
lacks. Among these are:
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem>
|
||||
<para>Certain extended <link
|
||||
linkend="invocationoptionsref">invocation options</link></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><link linkend="commandsubref">Command substitution</link> using
|
||||
<command>$( )</command> notation</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Certain <link linkend="stringmanip">string manipulation</link>
|
||||
operations</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><link linkend="processsubref">Process substitution</link></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Bash-specific <link linkend="builtinref">builtins</link></para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>See the <ulink url="ftp://ftp.cwru.edu/pub/bash/FAQ">Bash
|
||||
F.A.Q.</ulink> for a complete listing.</para>
|
||||
|
||||
</sect1> <!-- Portability Issues -->
|
||||
|
||||
|
@ -23035,7 +23289,7 @@ fi</programlisting>
|
|||
an instructive example script.</para>
|
||||
|
||||
<para>Many thanks to <ulink
|
||||
url="mailto:mikaku@arrakis.es">Jordi Sanfeliu</ulink>
|
||||
url="mailto:mikaku@fiwix.org">Jordi Sanfeliu</ulink>
|
||||
for giving permission to use his fine tree script (<xref
|
||||
linkend="tree">).</para>
|
||||
|
||||
|
@ -23075,6 +23329,10 @@ fi</programlisting>
|
|||
linkend="cutref">cut</link> and <link
|
||||
linkend="pidofref">pidof</link>.</para>
|
||||
|
||||
<para>Michael Zick extended the <link linkend="emptyarray">empty
|
||||
array</link> example to demonstrate some surprising array
|
||||
properties. He also provided other examples of this.</para>
|
||||
|
||||
<para>Marc-Jano Knopp sent corrections on DOS batch files.</para>
|
||||
|
||||
<para>Hyun Jin Cha found several typos in the document in the
|
||||
|
@ -23162,18 +23420,18 @@ fi</programlisting>
|
|||
<author><firstname>Aeleen</firstname><surname>Frisch</surname></author>
|
||||
</authorgroup>
|
||||
<title>Essential System Administration</title>
|
||||
<edition>2nd edition</edition>
|
||||
<edition>3rd edition</edition>
|
||||
<publisher>
|
||||
<publishername>O'Reilly and Associates</publishername>
|
||||
</publisher>
|
||||
<copyright>
|
||||
<year>1995</year>
|
||||
<year>2002</year>
|
||||
</copyright>
|
||||
<isbn>1-56592-127-5</isbn>
|
||||
<isbn>0-596-00343-9</isbn>
|
||||
<abstract><para>This excellent sys admin manual has a decent introduction to shell
|
||||
scripting for sys administrators and does a nice job of explaining the
|
||||
startup and initialization scripts. The book is long overdue for a third
|
||||
edition (are you listening, Tim O'Reilly?).</para>
|
||||
startup and initialization scripts. The long overdue third edition of this
|
||||
classic has finally been released.</para>
|
||||
<para>*</para>
|
||||
</abstract>
|
||||
</biblioentry>
|
||||
|
@ -23459,21 +23717,20 @@ fi</programlisting>
|
|||
|
||||
<biblioentry>
|
||||
<title>The UNIX CD Bookshelf</title>
|
||||
<edition>2nd edition</edition>
|
||||
<edition>3rd edition</edition>
|
||||
<publisher>
|
||||
<publishername>O'Reilly and Associates</publishername>
|
||||
</publisher>
|
||||
<copyright>
|
||||
<year>2000</year>
|
||||
<year>2003</year>
|
||||
</copyright>
|
||||
<isbn>1-56592-815-6</isbn>
|
||||
<abstract><para>An array of six UNIX books on CD ROM, including
|
||||
<isbn>0-596-00392-7</isbn>
|
||||
<abstract><para>An array of seven UNIX books on CD ROM, including
|
||||
<emphasis>UNIX Power Tools</emphasis>, <emphasis>Sed
|
||||
and Awk</emphasis>, and <emphasis>Learning the Korn
|
||||
Shell</emphasis>. A complete set of all the UNIX references
|
||||
and tutorials you would ever need at about $70. Buy this one,
|
||||
and tutorials you would ever need at about $130. Buy this one,
|
||||
even if it means going into debt and not paying the rent.</para>
|
||||
<para>Unfortunately, out of print at present.</para>
|
||||
<para>*</para>
|
||||
</abstract>
|
||||
</biblioentry>
|
||||
|
@ -23545,8 +23802,7 @@ fi</programlisting>
|
|||
<biblioentry>
|
||||
<abstract>
|
||||
<para>Example shell scripts at <ulink
|
||||
url="http://www.oase-shareware.org/shell/scripts">SHELLdorado
|
||||
</ulink>.</para>
|
||||
url="http://www.shelldorado.com">SHELLdorado </ulink>.</para>
|
||||
</abstract>
|
||||
</biblioentry>
|
||||
|
||||
|
@ -23577,19 +23833,11 @@ fi</programlisting>
|
|||
<biblioentry>
|
||||
<abstract>
|
||||
<para>Giles Orr's <ulink
|
||||
url="http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO.html">Bash-Prompt
|
||||
url="http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/">Bash-Prompt
|
||||
HOWTO</ulink>.</para>
|
||||
</abstract>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry>
|
||||
<abstract>
|
||||
<para>The <ulink
|
||||
url="http://www.dbnet.ece.ntua.gr/~george/howto/sed/">sed F.A.Q. /
|
||||
Do It With Sed</ulink>.</para>
|
||||
</abstract>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry>
|
||||
<abstract>
|
||||
<para>Very nice <command>sed</command>,
|
||||
|
@ -23599,6 +23847,14 @@ fi</programlisting>
|
|||
</abstract>
|
||||
</biblioentry>
|
||||
|
||||
<biblioentry>
|
||||
<abstract>
|
||||
<para>Eric Pement's
|
||||
<ulink url="http://www.student.northpark.edu/pemente/sed/">sed resources page</ulink>.</para>
|
||||
</abstract>
|
||||
</biblioentry>
|
||||
|
||||
|
||||
<biblioentry>
|
||||
<abstract>
|
||||
<para>The GNU <command>gawk</command> <ulink
|
||||
|
@ -23839,6 +24095,16 @@ fi</programlisting>
|
|||
<programlisting>&string;</programlisting>
|
||||
</example>
|
||||
|
||||
<para>Michael Zick's complex array example uses the <link
|
||||
linkend="md5sumref">md5sum</link> check sum command to encode directory
|
||||
information.</para>
|
||||
|
||||
<example id="directoryinfo">
|
||||
<title>Directory information</title>
|
||||
<programlisting>&directoryinfo;</programlisting>
|
||||
</example>
|
||||
|
||||
|
||||
<para>Stephane Chazelas demonstrates object-oriented programming in a
|
||||
Bash script.</para>
|
||||
|
||||
|
|
|
@ -1,19 +1,26 @@
|
|||
#===============================================================
|
||||
#
|
||||
# PERSONAL $HOME/.bashrc FILE for bash-2.05 (or later)
|
||||
# PERSONAL $HOME/.bashrc FILE for bash-2.05a (or later)
|
||||
#
|
||||
# Last modified: Tue Apr 15 20:32:34 CEST 2003
|
||||
#
|
||||
# This file is read (normally) by interactive shells only.
|
||||
# Here is the place to define your aliases, functions and
|
||||
# other interactive features like your prompt.
|
||||
#
|
||||
# This file was designed (originally) for Solaris.
|
||||
# This file was designed (originally) for Solaris but based
|
||||
# on Redhat's default .bashrc file
|
||||
# --> Modified for Linux.
|
||||
# The majority of the code you'll find here is based on code found
|
||||
# on Usenet (or internet).
|
||||
# This bashrc file is a bit overcrowded - remember it is just
|
||||
# just an example. Tailor it to your needs
|
||||
# just an example. Tailor it to your needs
|
||||
#
|
||||
#
|
||||
#===============================================================
|
||||
|
||||
# --> Comments added by HOWTO author.
|
||||
# --> And then edited again by ER :-)
|
||||
|
||||
#-----------------------------------
|
||||
# Source global definitions (if any)
|
||||
|
@ -25,38 +32,69 @@ fi
|
|||
|
||||
#-------------------------------------------------------------
|
||||
# Automatic setting of $DISPLAY (if not set already)
|
||||
# This works for linux and solaris - your mileage may vary....
|
||||
# This works for linux - your mileage may vary....
|
||||
# The problem is that different types of terminals give
|
||||
# different answers to 'who am i'......
|
||||
# I have not found a 'universal' method yet
|
||||
#-------------------------------------------------------------
|
||||
|
||||
function get_xserver ()
|
||||
{
|
||||
case $TERM in
|
||||
xterm )
|
||||
XSERVER=$(who am i | awk '{print $NF}' | tr -d ')''(' )
|
||||
XSERVER=${XSERVER%%:*}
|
||||
;;
|
||||
aterm | rxvt)
|
||||
# find some code that works here.....
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ -z ${DISPLAY:=""} ]; then
|
||||
DISPLAY=$(who am i)
|
||||
DISPLAY=${DISPLAY%%\!*}
|
||||
if [ -n "$DISPLAY" ]; then
|
||||
export DISPLAY=$DISPLAY:0.0
|
||||
else
|
||||
export DISPLAY=":0.0" # fallback
|
||||
get_xserver
|
||||
if [[ -z ${XSERVER} || ${XSERVER} == $(hostname) || ${XSERVER} == "unix" ]]; then
|
||||
DISPLAY=":0.0" # Display on local host
|
||||
else
|
||||
DISPLAY=${XSERVER}:0.0 # Display on remote host
|
||||
fi
|
||||
fi
|
||||
|
||||
export DISPLAY
|
||||
|
||||
#---------------
|
||||
# Some settings
|
||||
#---------------
|
||||
|
||||
ulimit -S -c 0 # Don't want any coredumps
|
||||
set -o notify
|
||||
set -o noclobber
|
||||
set -o ignoreeof
|
||||
set -o nounset
|
||||
#set -o xtrace # useful for debuging
|
||||
|
||||
# Enable options:
|
||||
shopt -s cdspell
|
||||
shopt -s cdable_vars
|
||||
shopt -s checkhash
|
||||
shopt -s checkwinsize
|
||||
shopt -s mailwarn
|
||||
shopt -s sourcepath
|
||||
shopt -s no_empty_cmd_completion
|
||||
shopt -s histappend histreedit
|
||||
shopt -s extglob # useful for programmable completion
|
||||
shopt -s no_empty_cmd_completion # bash>=2.04 only
|
||||
shopt -s cmdhist
|
||||
shopt -s histappend histreedit histverify
|
||||
shopt -s extglob # necessary for programmable completion
|
||||
|
||||
# Disable options:
|
||||
shopt -u mailwarn
|
||||
unset MAILCHECK # I don't want my shell to warn me of incoming mail
|
||||
|
||||
|
||||
export TIMEFORMAT=$'\nreal %3R\tuser %3U\tsys %3S\tpcpu %P\n'
|
||||
export HISTIGNORE="&:bg:fg:ll:h"
|
||||
export HOSTFILE=$HOME/.hosts # Put a list of remote hosts in ~/.hosts
|
||||
|
||||
|
||||
|
||||
#-----------------------
|
||||
# Greeting, motd etc...
|
||||
|
@ -75,26 +113,37 @@ NC='\e[0m' # No Color
|
|||
# Looks best on a black background.....
|
||||
echo -e "${CYAN}This is BASH ${RED}${BASH_VERSION%.*}${CYAN} - DISPLAY on ${RED}$DISPLAY${NC}\n"
|
||||
date
|
||||
if [ -x /usr/games/fortune ]; then
|
||||
if [ -x /usr/games/fortune ]; then
|
||||
/usr/games/fortune -s # makes our day a bit more fun.... :-)
|
||||
fi
|
||||
|
||||
function _exit() # function to run upon exit of shell
|
||||
function _exit() # function to run upon exit of shell
|
||||
{
|
||||
echo -e "${RED}Hasta la vista, baby${NC}"
|
||||
}
|
||||
trap _exit 0
|
||||
trap _exit EXIT
|
||||
|
||||
#---------------
|
||||
# Shell prompt
|
||||
# Shell Prompt
|
||||
#---------------
|
||||
|
||||
if [[ "${DISPLAY#$HOST}" != ":0.0" && "${DISPLAY}" != ":0" ]]; then
|
||||
HILIT=${red} # remote machine: prompt will be partly red
|
||||
else
|
||||
HILIT=${cyan} # local machine: prompt will be partly cyan
|
||||
fi
|
||||
|
||||
# --> Replace instances of \W with \w in prompt functions below
|
||||
#+ --> to get display of full path name.
|
||||
|
||||
function fastprompt()
|
||||
{
|
||||
unset PROMPT_COMMAND
|
||||
case $TERM in
|
||||
*term | rxvt )
|
||||
PS1="[\h] \W > \[\033]0;[\u@\h] \w\007\]" ;;
|
||||
PS1="${HILIT}[\h]$NC \W > \[\033]0;\${TERM} [\u@\h] \w\007\]" ;;
|
||||
linux )
|
||||
PS1="${HILIT}[\h]$NC \W > " ;;
|
||||
*)
|
||||
PS1="[\h] \W > " ;;
|
||||
esac
|
||||
|
@ -105,17 +154,16 @@ function powerprompt()
|
|||
_powerprompt()
|
||||
{
|
||||
LOAD=$(uptime|sed -e "s/.*: \([^,]*\).*/\1/" -e "s/ //g")
|
||||
TIME=$(date +%H:%M)
|
||||
}
|
||||
|
||||
PROMPT_COMMAND=_powerprompt
|
||||
case $TERM in
|
||||
*term | rxvt )
|
||||
PS1="${cyan}[\$TIME \$LOAD]$NC\n[\h \#] \W > \[\033]0;[\u@\h] \w\007\]" ;;
|
||||
PS1="${HILIT}[\A \$LOAD]$NC\n[\h \#] \W > \[\033]0;\${TERM} [\u@\h] \w\007\]" ;;
|
||||
linux )
|
||||
PS1="${cyan}[\$TIME - \$LOAD]$NC\n[\h \#] \w > " ;;
|
||||
PS1="${HILIT}[\A - \$LOAD]$NC\n[\h \#] \w > " ;;
|
||||
* )
|
||||
PS1="[\$TIME - \$LOAD]\n[\h \#] \w > " ;;
|
||||
PS1="[\A - \$LOAD]\n[\h \#] \w > " ;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
@ -144,6 +192,7 @@ alias rm='rm -i'
|
|||
alias cp='cp -i'
|
||||
alias mv='mv -i'
|
||||
# -> Prevents accidentally clobbering files.
|
||||
alias mkdir='mkdir -p'
|
||||
|
||||
alias h='history'
|
||||
alias j='jobs -l'
|
||||
|
@ -151,23 +200,23 @@ alias r='rlogin'
|
|||
alias which='type -all'
|
||||
alias ..='cd ..'
|
||||
alias path='echo -e ${PATH//:/\\n}'
|
||||
alias print='/usr/bin/lp -o nobanner -d $LPDEST' # Assumes LPDEST is defined
|
||||
alias print='/usr/bin/lp -o nobanner -d $LPDEST' # Assumes LPDEST is defined
|
||||
alias pjet='enscript -h -G -fCourier9 -d $LPDEST' # Pretty-print using enscript
|
||||
alias background='xv -root -quit -max -rmode 5' # put a picture in the background
|
||||
alias vi='vim'
|
||||
alias du='du -h'
|
||||
alias df='df -kh'
|
||||
alias background='xv -root -quit -max -rmode 5' # Put a picture in the background
|
||||
alias du='du -kh'
|
||||
alias df='df -kTh'
|
||||
|
||||
# The 'ls' family (this assumes you use the GNU ls)
|
||||
alias la='ls -Al' # show hidden files
|
||||
alias ls='ls -hF --color' # add colors for filetype recognition
|
||||
alias lx='ls -lXB' # sort by extension
|
||||
alias lk='ls -lSr' # sort by size
|
||||
alias la='ls -Al' # show hidden files
|
||||
alias lr='ls -lR' # recursice ls
|
||||
alias lt='ls -ltr' # sort by date
|
||||
alias lm='ls -al |more' # pipe through 'more'
|
||||
alias tree='tree -Cs' # nice alternative to 'ls'
|
||||
|
||||
alias lx='ls -lXB' # sort by extension
|
||||
alias lk='ls -lSr' # sort by size
|
||||
alias lc='ls -lcr' # sort by change time
|
||||
alias lu='ls -lur' # sort by access time
|
||||
alias lr='ls -lR' # recursive ls
|
||||
alias lt='ls -ltr' # sort by date
|
||||
alias lm='ls -al |more' # pipe through 'more'
|
||||
alias tree='tree -Csu' # nice alternative to 'ls'
|
||||
|
||||
# tailoring 'less'
|
||||
alias more='less'
|
||||
|
@ -190,10 +239,11 @@ alias kk='ll'
|
|||
|
||||
function xtitle ()
|
||||
{
|
||||
case $TERM in
|
||||
case "$TERM" in
|
||||
*term | rxvt)
|
||||
echo -n -e "\033]0;$*\007" ;;
|
||||
*) ;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
@ -202,21 +252,22 @@ alias top='xtitle Processes on $HOST && top'
|
|||
alias make='xtitle Making $(basename $PWD) ; make'
|
||||
alias ncftp="xtitle ncFTP ; ncftp"
|
||||
|
||||
# .. and functions
|
||||
# .. and functions
|
||||
function man ()
|
||||
{
|
||||
xtitle The $(basename $1|tr -d .[:digit:]) manual
|
||||
man -a "$*"
|
||||
for i ; do
|
||||
xtitle The $(basename $1|tr -d .[:digit:]) manual
|
||||
command man -F -a "$i"
|
||||
done
|
||||
}
|
||||
|
||||
function ll(){ ls -l "$@"| egrep "^d" ; ls -lXB "$@" 2>&-| egrep -v "^d|total "; }
|
||||
function xemacs() { { command xemacs -private $* 2>&- & } && disown ;}
|
||||
function te() # wrapper around xemacs/gnuserv
|
||||
{
|
||||
if [ "$(gnuclient -batch -eval t 2>&-)" == "t" ]; then
|
||||
gnuclient -q "$@";
|
||||
else
|
||||
( xemacs "$@" & );
|
||||
( xemacs "$@" &);
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -224,18 +275,33 @@ function te() # wrapper around xemacs/gnuserv
|
|||
# File & strings related functions:
|
||||
#-----------------------------------
|
||||
|
||||
function ff() { find . -name '*'$1'*' ; } # find a file
|
||||
function fe() { find . -name '*'$1'*' -exec $2 {} \; ; } # find a file and run $2 on it
|
||||
function fstr() # find a string in a set of files
|
||||
# Find a file with a pattern in name:
|
||||
function ff() { find . -type f -iname '*'$*'*' -ls ; }
|
||||
# Find a file with pattern $1 in name and Execute $2 on it:
|
||||
function fe() { find . -type f -iname '*'$1'*' -exec "${2:-file}" {} \; ; }
|
||||
# find pattern in a set of filesand highlight them:
|
||||
function fstr()
|
||||
{
|
||||
if [ "$#" -gt 2 ]; then
|
||||
echo "Usage: fstr \"pattern\" [files] "
|
||||
OPTIND=1
|
||||
local case=""
|
||||
local usage="fstr: find string in files.
|
||||
Usage: fstr [-i] \"pattern\" [\"filename pattern\"] "
|
||||
while getopts :it opt
|
||||
do
|
||||
case "$opt" in
|
||||
i) case="-i " ;;
|
||||
*) echo "$usage"; return;;
|
||||
esac
|
||||
done
|
||||
shift $(( $OPTIND - 1 ))
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echo "$usage"
|
||||
return;
|
||||
fi
|
||||
SMSO=$(tput smso)
|
||||
RMSO=$(tput rmso)
|
||||
find . -type f -name "${2:-*}" -print | xargs grep -sin "$1" | \
|
||||
sed "s/$1/$SMSO$1$RMSO/gI"
|
||||
local SMSO=$(tput smso)
|
||||
local RMSO=$(tput rmso)
|
||||
find . -type f -name "${2:-*}" -print0 | xargs -0 grep -sn ${case} "$1" 2>&- | \
|
||||
sed "s/$1/${SMSO}\0${RMSO}/gI" | more
|
||||
}
|
||||
|
||||
function cuttail() # cut last n lines in file, 10 by default
|
||||
|
@ -266,11 +332,12 @@ function lowercase() # move filenames to lowercase
|
|||
function swap() # swap 2 filenames around
|
||||
{
|
||||
local TMPFILE=tmp.$$
|
||||
mv $1 $TMPFILE
|
||||
mv $2 $1
|
||||
mv $TMPFILE $2
|
||||
mv "$1" $TMPFILE
|
||||
mv "$2" "$1"
|
||||
mv $TMPFILE "$2"
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------
|
||||
# Process/system related functions:
|
||||
#-----------------------------------
|
||||
|
@ -283,16 +350,16 @@ function pp() { my_ps f | awk '!/awk/ && $0~var' var=${1:-".*"} ; }
|
|||
function killps() # kill by process name
|
||||
{
|
||||
local pid pname sig="-TERM" # default signal
|
||||
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
|
||||
echo "Usage: killps [-SIGNAL] pattern"
|
||||
return;
|
||||
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
|
||||
echo "Usage: killps [-SIGNAL] pattern"
|
||||
return;
|
||||
fi
|
||||
if [ $# = 2 ]; then sig=$1 ; fi
|
||||
for pid in $(my_ps| awk '!/awk/ && $0~pat { print $1 }' pat=${!#} ) ; do
|
||||
pname=$(my_ps | awk '$1~var { print $5 }' var=$pid )
|
||||
if ask "Kill process $pid <$pname> with signal $sig?"
|
||||
then kill $sig $pid
|
||||
fi
|
||||
pname=$(my_ps | awk '$1~var { print $5 }' var=$pid )
|
||||
if ask "Kill process $pid <$pname> with signal $sig?"
|
||||
then kill $sig $pid
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
@ -316,7 +383,6 @@ function ii() # get current host related info
|
|||
echo
|
||||
}
|
||||
|
||||
|
||||
# Misc utilities:
|
||||
|
||||
function repeat() # repeat n times command
|
||||
|
@ -328,7 +394,6 @@ function repeat() # repeat n times command
|
|||
done
|
||||
}
|
||||
|
||||
|
||||
function ask()
|
||||
{
|
||||
echo -n "$@" '[y/n] ' ; read ans
|
||||
|
@ -341,8 +406,9 @@ function ask()
|
|||
#=========================================================================
|
||||
#
|
||||
# PROGRAMMABLE COMPLETION - ONLY SINCE BASH-2.04
|
||||
# (Most are taken from the bash 2.05 documentation)
|
||||
# You will in fact need bash-2.05 for some features
|
||||
# Most are taken from the bash 2.05 documentation and from Ian McDonalds
|
||||
# 'Bash completion' package (http://www.caliban.org/bash/index.shtml#completion)
|
||||
# You will in fact need bash-2.05a for some features
|
||||
#
|
||||
#=========================================================================
|
||||
|
||||
|
@ -352,11 +418,9 @@ if [ "${BASH_VERSION%.*}" \< "2.05" ]; then
|
|||
fi
|
||||
|
||||
shopt -s extglob # necessary
|
||||
set +o nounset # otherwise some completions will fail
|
||||
set +o nounset # otherwise some completions will fail
|
||||
|
||||
complete -A hostname rsh rcp telnet rlogin r ftp ping disk
|
||||
complete -A command nohup exec eval trace gdb
|
||||
complete -A command command type which
|
||||
complete -A export printenv
|
||||
complete -A variable export local readonly unset
|
||||
complete -A enabled builtin
|
||||
|
@ -372,40 +436,57 @@ complete -A job -P '%' fg jobs disown
|
|||
complete -A directory mkdir rmdir
|
||||
complete -A directory -o default cd
|
||||
|
||||
complete -f -d -X '*.gz' gzip
|
||||
complete -f -d -X '*.bz2' bzip2
|
||||
complete -f -o default -X '!*.gz' gunzip
|
||||
complete -f -o default -X '!*.bz2' bunzip2
|
||||
complete -f -o default -X '!*.pl' perl perl5
|
||||
# Compression
|
||||
complete -f -o default -X '*.+(zip|ZIP)' zip
|
||||
complete -f -o default -X '!*.+(zip|ZIP)' unzip
|
||||
complete -f -o default -X '*.+(z|Z)' compress
|
||||
complete -f -o default -X '!*.+(z|Z)' uncompress
|
||||
complete -f -o default -X '*.+(gz|GZ)' gzip
|
||||
complete -f -o default -X '!*.+(gz|GZ)' gunzip
|
||||
complete -f -o default -X '*.+(bz2|BZ2)' bzip2
|
||||
complete -f -o default -X '!*.+(bz2|BZ2)' bunzip2
|
||||
# Postscript,pdf,dvi.....
|
||||
complete -f -o default -X '!*.ps' gs ghostview ps2pdf ps2ascii
|
||||
complete -f -o default -X '!*.dvi' dvips dvipdf xdvi dviselect dvitype
|
||||
complete -f -o default -X '!*.pdf' acroread pdf2ps
|
||||
complete -f -o default -X '!*.+(pdf|ps)' gv
|
||||
complete -f -o default -X '!*.pdf' acroread pdf2ps
|
||||
complete -f -o default -X '!*.+(pdf|ps)' gv
|
||||
complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf
|
||||
complete -f -o default -X '!*.tex' tex latex slitex
|
||||
complete -f -o default -X '!*.lyx' lyx
|
||||
complete -f -o default -X '!*.+(jpg|gif|xpm|png|bmp)' xv gimp
|
||||
complete -f -o default -X '!*.mp3' mpg123
|
||||
complete -f -o default -X '!*.ogg' ogg123
|
||||
complete -f -o default -X '!*.tex' tex latex slitex
|
||||
complete -f -o default -X '!*.lyx' lyx
|
||||
complete -f -o default -X '!*.+(htm*|HTM*)' lynx html2ps
|
||||
# Multimedia
|
||||
complete -f -o default -X '!*.+(jp*g|gif|xpm|png|bmp)' xv gimp
|
||||
complete -f -o default -X '!*.+(mp3|MP3)' mpg123 mpg321
|
||||
complete -f -o default -X '!*.+(ogg|OGG)' ogg123
|
||||
|
||||
|
||||
|
||||
complete -f -o default -X '!*.pl' perl perl5
|
||||
|
||||
# This is a 'universal' completion function - it works when commands have
|
||||
# a so-called 'long options' mode , ie: 'ls --all' instead of 'ls -a'
|
||||
_universal_func ()
|
||||
# a so-called 'long options' mode , ie: 'ls --all' instead of 'ls -a'
|
||||
|
||||
_get_longopts ()
|
||||
{
|
||||
$1 --help | sed -e '/--/!d' -e 's/.*--\([^[:space:].,]*\).*/--\1/'| \
|
||||
grep ^"$2" |sort -u ;
|
||||
}
|
||||
|
||||
_longopts_func ()
|
||||
{
|
||||
case "$2" in
|
||||
case "${2:-*}" in
|
||||
-*) ;;
|
||||
*) return ;;
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
\~*) eval cmd=$1 ;;
|
||||
\~*) eval cmd="$1" ;;
|
||||
*) cmd="$1" ;;
|
||||
esac
|
||||
COMPREPLY=( $("$cmd" --help | sed -e '/--/!d' -e 's/.*--\([^ ]*\).*/--\1/'| \
|
||||
grep ^"$2" |sort -u) )
|
||||
COMPREPLY=( $(_get_longopts ${1} ${2} ) )
|
||||
}
|
||||
complete -o default -F _universal_func ldd wget bash id info
|
||||
complete -o default -F _longopts_func configure bash
|
||||
complete -o default -F _longopts_func wget id info a2ps ls recode
|
||||
|
||||
|
||||
_make_targets ()
|
||||
|
@ -459,22 +540,6 @@ _make_targets ()
|
|||
|
||||
complete -F _make_targets -X '+($*|*.[cho])' make gmake pmake
|
||||
|
||||
_configure_func ()
|
||||
{
|
||||
case "$2" in
|
||||
-*) ;;
|
||||
*) return ;;
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
\~*) eval cmd=$1 ;;
|
||||
*) cmd="$1" ;;
|
||||
esac
|
||||
|
||||
COMPREPLY=( $("$cmd" --help | awk '{if ($1 ~ /--.*/) print $1}' | grep ^"$2" | sort -u) )
|
||||
}
|
||||
|
||||
complete -F _configure_func configure
|
||||
|
||||
# cvs(1) completion
|
||||
_cvs ()
|
||||
|
@ -485,17 +550,16 @@ _cvs ()
|
|||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
if [ $COMP_CWORD -eq 1 ] || [ "${prev:0:1}" = "-" ]; then
|
||||
COMPREPLY=( $( compgen -W 'add admin checkout commit diff \
|
||||
export history import log rdiff release remove rtag status \
|
||||
tag update' $cur ))
|
||||
COMPREPLY=( $( compgen -W 'add admin checkout commit diff \
|
||||
export history import log rdiff release remove rtag status \
|
||||
tag update' $cur ))
|
||||
else
|
||||
COMPREPLY=( $( compgen -f $cur ))
|
||||
COMPREPLY=( $( compgen -f $cur ))
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
complete -F _cvs cvs
|
||||
|
||||
|
||||
_killall ()
|
||||
{
|
||||
local cur prev
|
||||
|
@ -514,6 +578,60 @@ _killall ()
|
|||
|
||||
complete -F _killall killall killps
|
||||
|
||||
|
||||
# A meta-command completion function for commands like sudo(8), which need to
|
||||
# first complete on a command, then complete according to that command's own
|
||||
# completion definition - currently not quite foolproof (e.g. mount and umount
|
||||
# don't work properly), but still quite useful - By Ian McDonald, modified by me.
|
||||
|
||||
_my_command()
|
||||
{
|
||||
local cur func cline cspec
|
||||
|
||||
COMPREPLY=()
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
|
||||
if [ $COMP_CWORD = 1 ]; then
|
||||
COMPREPLY=( $( compgen -c $cur ) )
|
||||
elif complete -p ${COMP_WORDS[1]} &>/dev/null; then
|
||||
cspec=$( complete -p ${COMP_WORDS[1]} )
|
||||
if [ "${cspec%%-F *}" != "${cspec}" ]; then
|
||||
# complete -F <function>
|
||||
#
|
||||
# COMP_CWORD and COMP_WORDS() are not read-only,
|
||||
# so we can set them before handing off to regular
|
||||
# completion routine
|
||||
|
||||
# set current token number to 1 less than now
|
||||
COMP_CWORD=$(( $COMP_CWORD - 1 ))
|
||||
# get function name
|
||||
func=${cspec#*-F }
|
||||
func=${func%% *}
|
||||
# get current command line minus initial command
|
||||
cline="${COMP_LINE#$1 }"
|
||||
# split current command line tokens into array
|
||||
COMP_WORDS=( $cline )
|
||||
$func $cline
|
||||
elif [ "${cspec#*-[abcdefgjkvu]}" != "" ]; then
|
||||
# complete -[abcdefgjkvu]
|
||||
#func=$( echo $cspec | sed -e 's/^.*\(-[abcdefgjkvu]\).*$/\1/' )
|
||||
func=$( echo $cspec | sed -e 's/^complete//' -e 's/[^ ]*$//' )
|
||||
COMPREPLY=( $( eval compgen $func $cur ) )
|
||||
elif [ "${cspec#*-A}" != "$cspec" ]; then
|
||||
# complete -A <type>
|
||||
func=${cspec#*-A }
|
||||
func=${func%% *}
|
||||
COMPREPLY=( $( compgen -A $func $cur ) )
|
||||
fi
|
||||
else
|
||||
COMPREPLY=( $( compgen -f $cur ) )
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
complete -o default -F _my_command nohup exec eval trace truss strace sotruss gdb
|
||||
complete -o default -F _my_command command type which man nice
|
||||
|
||||
# Local Variables:
|
||||
# mode:shell-script
|
||||
# sh-shell:bash
|
||||
|
|
|
@ -81,7 +81,7 @@ echo "File \"$file\" blotted out and deleted."; echo
|
|||
# For an in-depth analysis on the topic of file deletion and security,
|
||||
#+ see Peter Gutmann's paper,
|
||||
#+ "Secure Deletion of Data From Magnetic and Solid-State Memory".
|
||||
# http://www.cs.auckland.ac.nz/~pgut001/secure_del.html
|
||||
# http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html
|
||||
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -24,10 +24,16 @@ do
|
|||
filename=${file%.*c} # Strip ".mac" suffix off filename
|
||||
#+ ('.*c' matches everything
|
||||
#+ between '.' and 'c', inclusive).
|
||||
$OPERATION $file > $filename.$SUFFIX
|
||||
$OPERATION $file > "$filename.$SUFFIX"
|
||||
# Redirect conversion to new filename.
|
||||
rm -f $file # Delete original files after converting.
|
||||
echo "$filename.$SUFFIX" # Log what is happening to stdout.
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
||||
# Exercise:
|
||||
# --------
|
||||
# As it stands, this script converts *all* the files in the current
|
||||
#+ working directory.
|
||||
# Modify it to work *only* on files with a ".mac" suffix.
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#!/bin/bash
|
||||
# empty-array.sh
|
||||
|
||||
# Thanks to Stephane Chazelas for the original example,
|
||||
#+ and to Michael Zick for extending it.
|
||||
|
||||
|
||||
# An empty array is not the same as an array with empty elements.
|
||||
|
||||
array0=( first second third )
|
||||
|
@ -8,7 +12,9 @@ array1=( '' ) # "array1" has one empty element.
|
|||
array2=( ) # No elements... "array2" is empty.
|
||||
|
||||
echo
|
||||
|
||||
ListArray()
|
||||
{
|
||||
echo
|
||||
echo "Elements in array0: ${array0[@]}"
|
||||
echo "Elements in array1: ${array1[@]}"
|
||||
echo "Elements in array2: ${array2[@]}"
|
||||
|
@ -20,7 +26,101 @@ echo
|
|||
echo "Number of elements in array0 = ${#array0[*]}" # 3
|
||||
echo "Number of elements in array1 = ${#array1[*]}" # 1 (surprise!)
|
||||
echo "Number of elements in array2 = ${#array2[*]}" # 0
|
||||
}
|
||||
|
||||
# ===================================================================
|
||||
|
||||
ListArray
|
||||
|
||||
# Try extending those arrays
|
||||
|
||||
# Adding an element to an array.
|
||||
array0=( "${array0[@]}" "new1" )
|
||||
array1=( "${array1[@]}" "new1" )
|
||||
array2=( "${array2[@]}" "new1" )
|
||||
|
||||
ListArray
|
||||
|
||||
# or
|
||||
array0[${#array0[*]}]="new2"
|
||||
array1[${#array1[*]}]="new2"
|
||||
array2[${#array2[*]}]="new2"
|
||||
|
||||
ListArray
|
||||
|
||||
# When extended as above; arrays are 'stacks'
|
||||
# The above is the 'push'
|
||||
# The stack 'height' is:
|
||||
height=${#array2[@]}
|
||||
echo
|
||||
echo "Stack height for array2 = $height"
|
||||
|
||||
exit 0 # Thanks, S.C.
|
||||
# The 'pop' is:
|
||||
unset array2[${#array2[@]}-1] # Arrays are zero based
|
||||
height=${#array2[@]}
|
||||
echo
|
||||
echo "POP"
|
||||
echo "New stack height for array2 = $height"
|
||||
|
||||
ListArray
|
||||
|
||||
# List only 2nd and 3rd elements of array0
|
||||
from=1 # Zero based numbering
|
||||
to=2 #
|
||||
declare -a array3=( ${array0[@]:1:2} )
|
||||
echo
|
||||
echo "Elements in array3: ${array3[@]}"
|
||||
|
||||
# Works like a string (array of characters)
|
||||
# Try some other "string" forms
|
||||
|
||||
# Replacement
|
||||
declare -a array4=( ${array0[@]/second/2nd} )
|
||||
echo
|
||||
echo "Elements in array4: ${array4[@]}"
|
||||
|
||||
# Replace all matching wildcarded string
|
||||
declare -a array5=( ${array0[@]//new?/old} )
|
||||
echo
|
||||
echo "Elements in array5: ${array5[@]}"
|
||||
|
||||
# Just when you are getting the feel for this...
|
||||
declare -a array6=( ${array0[@]#*new} )
|
||||
echo # This one might surprise you
|
||||
echo "Elements in array6: ${array6[@]}"
|
||||
|
||||
declare -a array7=( ${array0[@]#new1} )
|
||||
echo # After array6 this should not be a surprise
|
||||
echo "Elements in array7: ${array7[@]}"
|
||||
|
||||
# Which looks a lot like...
|
||||
declare -a array8=( ${array0[@]/new1/} )
|
||||
echo
|
||||
echo "Elements in array8: ${array8[@]}"
|
||||
|
||||
# So what can one say about this?
|
||||
|
||||
# The string operations are performed on
|
||||
#+ each of the elements in var[@] in succession.
|
||||
# Therefore : BASH supports string vector operations
|
||||
# If the result is a zero length string, that
|
||||
#+ element disappears in the resulting assignment.
|
||||
|
||||
# Question, are those strings hard or soft quotes?
|
||||
|
||||
zap='new*'
|
||||
declare -a array9=( ${array0[@]/$zap/} )
|
||||
echo
|
||||
echo "Elements in array9: ${array9[@]}"
|
||||
|
||||
# Just when you thought you where still in Kansas...
|
||||
declare -a array10=( ${array0[@]#$zap} )
|
||||
echo
|
||||
echo "Elements in array10: ${array10[@]}"
|
||||
|
||||
# Compare array7 with array10
|
||||
# Compare array8 with array9
|
||||
|
||||
# Answer, must be soft quotes.
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -17,3 +17,9 @@ echo >>logfile
|
|||
echo >>logfile
|
||||
|
||||
exit 0
|
||||
|
||||
# Exercise:
|
||||
# --------
|
||||
# Modify this script to track changes in /var/log/messages at intervals
|
||||
#+ of 20 minutes.
|
||||
# Hint: Use the "watch" command.
|
||||
|
|
|
@ -7,7 +7,7 @@ DOC_REQUEST=70
|
|||
if [ "$1" = "-h" -o "$1" = "--help" ] # Request help.
|
||||
then
|
||||
echo; echo "Usage: $0 [directory-name]"; echo
|
||||
cat "$0" | sed --silent -e '/DOCUMENTATIONXX$/,/^DOCUMENTATION/p' |
|
||||
sed --silent -e '/DOCUMENTATIONXX$/,/^DOCUMENTATION/p' "$0" |
|
||||
sed -e '/DOCUMENTATIONXX/d'; exit $DOC_REQUEST; fi
|
||||
|
||||
: << DOCUMENTATIONXX
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
# @(#) tree 1.1 30/11/95 by Jordi Sanfeliu
|
||||
# email: mikaku@arrakis.es
|
||||
# email: mikaku@fiwix.org
|
||||
#
|
||||
# Initial version: 1.0 30/11/95
|
||||
# Next version : 1.1 24/02/97 Now, with symbolic links
|
||||
|
|
Loading…
Reference in New Issue