📄 internal.html
字号:
NAME="EX43"></A><P><B>Example 11-11. Showing the effect of <BCLASS="COMMAND">eval</B></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 y=`eval ls -l` # Similar to y=`ls -l` 4 echo $y #+ but linefeeds removed because "echoed" variable is unquoted. 5 echo 6 echo "$y" # Linefeeds preserved when variable is quoted. 7 8 echo; echo 9 10 y=`eval df` # Similar to y=`df` 11 echo $y #+ but linefeeds removed. 12 13 # When LF's not preserved, it may make it easier to parse output, 14 #+ using utilities such as "awk". 15 16 echo 17 echo "===========================================================" 18 echo 19 20 # Now, showing how to "expand" a variable using "eval" . . . 21 22 for i in 1 2 3 4 5; do 23 eval value=$i 24 # value=$i has same effect. The "eval" is not necessary here. 25 # A variable lacking a meta-meaning evaluates to itself -- 26 #+ it can't expand to anything other than its literal self. 27 echo $value 28 done 29 30 echo 31 echo "---" 32 echo 33 34 for i in ls df; do 35 value=eval $i 36 # value=$i has an entirely different effect here. 37 # The "eval" evaluates the commands "ls" and "df" . . . 38 # The terms "ls" and "df" have a meta-meaning, 39 #+ since they are interpreted as commands, 40 #+ rather than just character strings. 41 echo $value 42 done 43 44 45 exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="EX44"></A><P><B>Example 11-12. Forcing a log-off</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # Killing ppp to force a log-off. 3 4 # Script should be run as root user. 5 6 killppp="eval kill -9 `ps ax | awk '/ppp/ { print $1 }'`" 7 # -------- process ID of ppp ------- 8 9 $killppp # This variable is now a command. 10 11 12 # The following operations must be done as root user. 13 14 chmod 666 /dev/ttyS3 # Restore read+write permissions, or else what? 15 # Since doing a SIGKILL on ppp changed the permissions on the serial port, 16 #+ we restore permissions to previous state. 17 18 rm /var/lock/LCK..ttyS3 # Remove the serial port lock file. Why? 19 20 exit 0 21 22 # Exercises: 23 # --------- 24 # 1) Have script check whether root user is invoking it. 25 # 2) Do a check on whether the process to be killed 26 #+ is actually running before attempting to kill it. 27 # 3) Write an alternate version of this script based on 'fuser': 28 #+ if [ fuser -s /dev/modem ]; then . . .</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="ROT14"></A><P><B>Example 11-13. A version of <SPANCLASS="QUOTE">"rot13"</SPAN></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # A version of "rot13" using 'eval'. 3 # Compare to "rot13.sh" example. 4 5 setvar_rot_13() # "rot13" scrambling 6 { 7 local varname=$1 varvalue=$2 8 eval $varname='$(echo "$varvalue" | tr a-z n-za-m)' 9 } 10 11 12 setvar_rot_13 var "foobar" # Run "foobar" through rot13. 13 echo $var # sbbone 14 15 setvar_rot_13 var "$var" # Run "sbbone" through rot13. 16 # Back to original variable. 17 echo $var # foobar 18 19 # This example by Stephane Chazelas. 20 # Modified by document author. 21 22 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>Rory Winston contributed the following instance of how useful <BCLASS="COMMAND">eval</B> can be.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EVALEX"></A><P><B>Example 11-14. Using <BCLASS="COMMAND">eval</B> to force variable substitution in a Perl script</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 In the Perl script "test.pl": 2 ... 3 my $WEBROOT = <WEBROOT_PATH>; 4 ... 5 6 To force variable substitution try: 7 $export WEBROOT_PATH=/usr/local/webroot 8 $sed 's/<WEBROOT_PATH>/$WEBROOT_PATH/' < test.pl > out 9 10 But this just gives: 11 my $WEBROOT = $WEBROOT_PATH; 12 13 However: 14 $export WEBROOT_PATH=/usr/local/webroot 15 $eval sed 's%\<WEBROOT_PATH\>%$WEBROOT_PATH%' < test.pl > out 16 # ==== 17 18 That works fine, and gives the expected substitution: 19 my $WEBROOT = /usr/local/webroot; 20 21 22 ### Correction applied to original example by Paulo Marcel Coelho Aragao.</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="CAUTION"><TABLECLASS="CAUTION"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/caution.png"HSPACE="5"ALT="Caution"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>The <BCLASS="COMMAND">eval</B> command can be risky, and normally should be avoided when there exists a reasonable alternative. An <TTCLASS="USERINPUT"><B>eval $COMMANDS</B></TT> executes the contents of <TTCLASS="REPLACEABLE"><I>COMMANDS</I></TT>, which may contain such unpleasant surprises as <BCLASS="COMMAND">rm -rf *</B>. Running an <BCLASS="COMMAND">eval</B> on unfamiliar code written by persons unknown is living dangerously.</P></TD></TR></TABLE></DIV></DD><DT><ANAME="SETREF"></A><BCLASS="COMMAND">set</B></DT><DD><P>The <BCLASS="COMMAND">set</B> command changes the value of internal script variables. One use for this is to toggle <AHREF="options.html#OPTIONSREF">option flags</A> which help determine the behavior of the script. Another application for it is to reset the <AHREF="variables2.html#POSPARAMREF">positional parameters</A> that a script sees as the result of a command (<TTCLASS="USERINPUT"><B>set `command`</B></TT>). The script can then parse the fields of the command output.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX34"></A><P><B>Example 11-15. Using <BCLASS="COMMAND">set</B> with positional parameters</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 # script "set-test" 4 5 # Invoke this script with three command line parameters, 6 # for example, "./set-test one two three". 7 8 echo 9 echo "Positional parameters before set \`uname -a\` :" 10 echo "Command-line argument #1 = $1" 11 echo "Command-line argument #2 = $2" 12 echo "Command-line argument #3 = $3" 13 14 15 set `uname -a` # Sets the positional parameters to the output 16 # of the command `uname -a` 17 18 echo $_ # unknown 19 # Flags set in script. 20 21 echo "Positional parameters after set \`uname -a\` :" 22 # $1, $2, $3, etc. reinitialized to result of `uname -a` 23 echo "Field #1 of 'uname -a' = $1" 24 echo "Field #2 of 'uname -a' = $2" 25 echo "Field #3 of 'uname -a' = $3" 26 echo --- 27 echo $_ # --- 28 echo 29 30 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>Invoking <BCLASS="COMMAND">set</B> without any options or arguments simply lists all the <AHREF="othertypesv.html#ENVREF">environmental</A> and other variables that have been initialized. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>set</B></TT> <TTCLASS="COMPUTEROUTPUT">AUTHORCOPY=/home/bozo/posts BASH=/bin/bash BASH_VERSION=$'2.05.8(1)-release' ... XAUTHORITY=/home/bozo/.Xauthority _=/etc/bashrc variable22=abc variable23=xzy</TT> </PRE></TD></TR></TABLE> </P><P>Using <BCLASS="COMMAND">set</B> with the <TTCLASS="OPTION">--</TT> option explicitly assigns the contents of a variable to the positional parameters. When no variable follows the <TTCLASS="OPTION">--</TT>, it <ICLASS="EMPHASIS">unsets</I> the positional parameters.</P><DIVCLASS="EXAMPLE"><HR><ANAME="SETPOS"></A><P><B>Example 11-16. Reassigning the positional parameters</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 variable="one two three four five" 4 5 set -- $variable 6 # Sets positional parameters to the contents of "$variable". 7 8 first_param=$1 9 second_param=$2 10 shift; shift # Shift past first two positional params. 11 remaining_params="$*" 12 13 echo 14 echo "first parameter = $first_param" # one 15 echo "second parameter = $second_param" # two 16 echo "remaining parameters = $remaining_params" # three four five 17 18 echo; echo 19 20 # Again. 21 set -- $variable 22 first_param=$1 23 second_param=$2 24 echo "first parameter = $first_param" # one 25 echo "second parameter = $second_param" # two 26 27 # ====================================================== 28 29 set -- 30 # Unsets positional parameters if no variable specified. 31 32 first_param=$1 33 second_param=$2 34 echo "first parameter = $first_param" # (null value) 35 echo "second parameter = $second_param" # (null value) 36 37 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>See also <AHREF="loops.html#EX22A">Example 10-2</A> and <AHREF="extmisc.html#EX33A">Example 12-51</A>.</P></DD><DT><ANAME="UNSETREF"></A><BCLASS="COMMAND">unset</B></DT><DD><P>The <BCLASS="COMMAND">unset</B> command deletes a shell variable, effectively setting it to <ICLASS="EMPHASIS">null</I>. Note that this command does not affect positional parameters.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>unset PATH</B></TT> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>echo $PATH</B></TT> <TTCLASS="COMPUTEROUTPUT"> </TT> <TTCLASS="PROMPT">bash$ </TT></PRE></TD></TR></TABLE> </P><DIVCLASS="EXAMPLE"><HR><ANAME="UNS"></A><P><B>Example 11-17. <SPANCLASS="QUOTE">"Unsetting"</SPAN> a variable</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # unset.sh: Unsetting a variable. 3 4 variable=hello # Initialized. 5 echo "variable = $variable" 6 7 unset variable # Unset. 8 # Same effect as: variable= 9 echo "(unset) variable = $variable" # $variable is null. 10 11 exit 0</PRE></TD></TR></TABLE><HR></DIV></DD><DT><ANAME="EXPORTREF"></A><BCLASS="COMMAND">export</B></DT><DD><P>The <BCLASS="COMMAND">export</B> command makes available variables to all child processes of the running script or shell. <ICLASS="EMPHASIS">Unfortunately, there is no way to</I> export <ICLASS="EMPHASIS">variables back to the parent process, to the process that called or invoked the script or shell.</I> One important use of the <BCLASS="COMMAND">export</B> command is in <AHREF="files.html#FILESREF1">startup files</A>, to initialize and make accessible <AHREF="othertypesv.html#ENVREF">environmental variables</A> to subsequent user processes.</P><DIVCLASS="EXAMPLE"><HR><ANAME="COLTOTALER3"></A><P><B>Example 11-18. Using <BCLASS="COMMAND">export</B> to pass a variable to an embedded <AHREF="awk.html#AWKREF">awk</A> script</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 # Yet another version of the "column totaler" script (col-totaler.sh) 4 #+ that adds up a specified column (of numbers) in the target file. 5 # This uses the environment to pass a script variable to 'awk' . . . 6 #+ and places the awk script in a variable. 7 8 9 ARGS=2 10 E_WRONGARGS=65 11 12 if [ $# -ne "$ARGS" ] # Check for proper no. of command line args. 13 then 14 echo "Usage: `basename $0` filename column-number" 15 exit $E_WRONGARGS 16 fi 17 18 filename=$1 19 column_number=$2 20 21 #===== Same as original script, up to this point =====# 22 23 export column_number 24 # Export column number to environment, so it's available for retrieval. 25 26 27 # ----------------------------------------------- 28 awkscript='{ total += $ENVIRON["column_number"] } 29 END { print total }' 30 # Yes, a variable can hold an awk script. 31 # ----------------------------------------------- 32 33 # Now, run the awk script.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -