📄 sha-bang.html
字号:
WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 E_WRONG_ARGS=65 2 script_parameters="-a -h -m -z" 3 # -a = all, -h = help, etc. 4 5 if [ $# -ne $Number_of_expected_args ] 6 then 7 echo "Usage: `basename $0` $script_parameters" 8 # `basename $0` is the script's filename. 9 exit $E_WRONG_ARGS 10 fi</PRE></TD></TR></TABLE> </P><P>Many times, you will write a script that carries out one particular task. The first script in this chapter is an example of this. Later, it might occur to you to generalize the script to do other, similar tasks. Replacing the literal (<SPANCLASS="QUOTE">"hard-wired"</SPAN>) constants by variables is a step in that direction, as is replacing repetitive code blocks by <AHREF="functions.html#FUNCTIONREF">functions</A>.</P></TD></TR></TABLE></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="INVOKING">2.1. Invoking the script</A></H1><P>Having written the script, you can invoke it by <TTCLASS="USERINPUT"><B>sh scriptname</B></TT>, <ANAME="AEN223"HREF="#FTN.AEN223">[5]</A> or alternatively <TTCLASS="USERINPUT"><B>bash scriptname</B></TT>. (Not recommended is using <TTCLASS="USERINPUT"><B>sh <scriptname</B></TT>, since this effectively disables reading from <TTCLASS="FILENAME">stdin</TT> within the script.) Much more convenient is to make the script itself directly executable with a <AHREF="external.html#CHMODREF">chmod</A>. <DIVCLASS="VARIABLELIST"><DL><DT>Either:</DT><DD><P><TTCLASS="USERINPUT"><B>chmod 555 scriptname</B></TT> (gives everyone read/execute permission) <ANAME="AEN236"HREF="#FTN.AEN236">[6]</A> </P></DD><DT>or</DT><DD><P><TTCLASS="USERINPUT"><B>chmod +rx scriptname</B></TT> (gives everyone read/execute permission)</P><P><TTCLASS="USERINPUT"><B>chmod u+rx scriptname</B></TT> (gives only the script owner read/execute permission)</P></DD></DL></DIV> </P><P>Having made the script executable, you may now test it by <TTCLASS="USERINPUT"><B>./scriptname</B></TT>. <ANAME="AEN248"HREF="#FTN.AEN248">[7]</A> If it begins with a <SPANCLASS="QUOTE">"sha-bang"</SPAN> line, invoking the script calls the correct command interpreter to run it.</P><P>As a final step, after testing and debugging, you would likely want to move it to <TTCLASS="FILENAME">/usr/local/bin</TT> (as root, of course), to make the script available to yourself and all other users as a system-wide executable. The script could then be invoked by simply typing <BCLASS="COMMAND">scriptname</B> <BCLASS="KEYCAP">[ENTER]</B> from the command line.</P></DIV></DIV><H3CLASS="FOOTNOTES">Notes</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN152"HREF="sha-bang.html#AEN152">[1]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>Some flavors of UNIX (those based on 4.2BSD) take a four-byte magic number, requiring a blank after the <SPANCLASS="TOKEN">!</SPAN> -- <TTCLASS="USERINPUT"><B>#! /bin/sh</B></TT>.</P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN163"HREF="sha-bang.html#AEN163">[2]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>The <SPANCLASS="TOKEN">#!</SPAN> line in a shell script will be the first thing the command interpreter (<BCLASS="COMMAND">sh</B> or <BCLASS="COMMAND">bash</B>) sees. Since this line begins with a <SPANCLASS="TOKEN">#</SPAN>, it will be correctly interpreted as a comment when the command interpreter finally executes the script. The line has already served its purpose - calling the command interpreter.</P><P>If, in fact, the script includes an <ICLASS="EMPHASIS">extra</I> <SPANCLASS="TOKEN">#!</SPAN> line, then <BCLASS="COMMAND">bash</B> will interpret it as a comment. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 echo "Part 1 of script." 4 a=1 5 6 #!/bin/bash 7 # This does *not* launch a new script. 8 9 echo "Part 2 of script." 10 echo $a # Value of $a stays at 1.</PRE></TD></TR></TABLE></P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN179"HREF="sha-bang.html#AEN179">[3]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>This allows some cute tricks.</P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/rm 2 # Self-deleting script. 3 4 # Nothing much seems to happen when you run this... except that the file disappears. 5 6 WHATEVER=65 7 8 echo "This line will never print (betcha!)." 9 10 exit $WHATEVER # Doesn't matter. The script will not exit here.</PRE></TD></TR></TABLE></P><P>Also, try starting a <TTCLASS="FILENAME">README</TT> file with a <TTCLASS="USERINPUT"><B>#!/bin/more</B></TT>, and making it executable. The result is a self-listing documentation file. (A <AHREF="here-docs.html#HEREDOCREF">here document</A> using <AHREF="external.html#CATREF">cat</A> is possibly a better alternative -- see <AHREF="here-docs.html#EX71">Example 17-3</A>).</P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN192"HREF="sha-bang.html#AEN192">[4]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P><ANAME="POSIX2REF"></A><ICLASS="EMPHASIS">P</I>ortable <ICLASS="EMPHASIS">O</I>perating <ICLASS="EMPHASIS">S</I>ystem <ICLASS="EMPHASIS">I</I>nterface, an attempt to standardize UNI<ICLASS="EMPHASIS">X</I>-like OSes. The POSIX specifications are listed on the <AHREF="http://www.opengroup.org/onlinepubs/007904975/toc.htm"TARGET="_top">Open Group site</A>.</P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN223"HREF="sha-bang.html#AEN223">[5]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>Caution: invoking a Bash script by <TTCLASS="USERINPUT"><B>sh scriptname</B></TT> turns off Bash-specific extensions, and the script may therefore fail to execute.</P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN236"HREF="sha-bang.html#AEN236">[6]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>A script needs <ICLASS="EMPHASIS">read</I>, as well as execute permission for it to run, since the shell needs to be able to read it.</P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN248"HREF="sha-bang.html#AEN248">[7]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>Why not simply invoke the script with <TTCLASS="USERINPUT"><B>scriptname</B></TT>? If the directory you are in (<AHREF="variables2.html#PWDREF">$PWD</A>) is where <ICLASS="EMPHASIS">scriptname</I> is located, why doesn't this work? This fails because, for security reasons, the current directory is not by default included in a user's <AHREF="variables2.html#PATHREF">$PATH</A>. It is therefore necessary to explicitly invoke the script in the current directory with a <TTCLASS="USERINPUT"><B>./scriptname</B></TT>.</P></TD></TR></TABLE><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLEWIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="why-shell.html">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="prelimexer.html">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Why Shell Programming?</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part1.html">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Preliminary Exercises</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -