📄 assortedtips.html
字号:
9 # command_test=$(whereis "$CMD" | grep \/) 10 # But then the sense of the following test would have to be reversed, 11 #+ since the $command_test variable holds content only if 12 #+ the $CMD exists on the system. 13 # (Thanks, bojster.) 14 15 16 if [[ -z "$command_test" ]] # Check whether command present. 17 then 18 $CMD option1 option2 # Run command1 with options. 19 else # Otherwise, 20 $PlanB #+ run command2. 21 fi</PRE></TD></TR></TABLE> </P></LI><LI><P><ANAME="IFGREPFIX"></A></P><P>An <AHREF="tests.html#IFGREPREF">if-grep test</A> may not return expected results in an error case, when text is output to <TTCLASS="FILENAME">stderr</TT>, rather that <TTCLASS="FILENAME">stdout</TT>. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 if ls -l nonexistent_filename | grep -q 'No such file or directory' 2 then echo "File \"nonexistent_filename\" does not exist." 3 fi</PRE></TD></TR></TABLE></P><P><AHREF="io-redirection.html#IOREDIRREF">Redirecting</A> <TTCLASS="FILENAME">stderr</TT> to <TTCLASS="FILENAME">stdout</TT> fixes this. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 if ls -l nonexistent_filename 2>&1 | grep -q 'No such file or directory' 2 # ^^^^ 3 then echo "File \"nonexistent_filename\" does not exist." 4 fi 5 6 # Thanks, Chris Martin, for pointing this out.</PRE></TD></TR></TABLE></P></LI><LI><P><ANAME="SUBSHTMP"></A> If you absolutely must access a subshell variable outside the subshell, here's a way to do it. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 TMPFILE=tmpfile # Create a temp file to store the variable. 2 3 ( # Inside the subshell ... 4 inner_variable=Inner 5 echo $inner_variable 6 echo $inner_variable >>$TMPFILE # Append to temp file. 7 ) 8 9 # Outside the subshell ... 10 11 echo; echo "-----"; echo 12 echo $inner_variable # Null, as expected. 13 echo "-----"; echo 14 15 # Now ... 16 read inner_variable <$TMPFILE # Read back shell variable. 17 rm -f "$TMPFILE" # Get rid of temp file. 18 echo "$inner_variable" # It's an ugly kludge, but it works.</PRE></TD></TR></TABLE> </P></LI><LI><P><ANAME="RUNPARTSREF2"></A></P><P>The <AHREF="extmisc.html#RUNPARTSREF">run-parts</A> command is handy for running a set of command scripts in a particular sequence, especially in combination with <AHREF="system.html#CRONREF">cron</A> or <AHREF="timedate.html#ATREF">at</A>.</P></LI><LI><P><ANAME="RCSREF"></A></P><P>For doing multiple revisions on a complex script, use the <ICLASS="FIRSTTERM">rcs</I> Revision Control System package.</P><P> Among other benefits of this is automatically updated ID header tags. The <BCLASS="COMMAND">co</B> command in <ICLASS="FIRSTTERM">rcs</I> does a parameter replacement of certain reserved key words, for example, replacing <TTCLASS="PARAMETER"><I>#$Id$</I></TT> in a script with something like: <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #$Id: hello-world.sh,v 1.1 2004/10/16 02:43:05 bozo Exp $</PRE></TD></TR></TABLE></P></LI></UL></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN19071"></A>33.8.2. Widgets</H2><P><ANAME="WIDGETREF"></A></P><P>It would be nice to be able to invoke X-Windows widgets from a shell script. There happen to exist several packages that purport to do so, namely <ICLASS="FIRSTTERM">Xscript</I>, <ICLASS="FIRSTTERM">Xmenu</I>, and <ICLASS="FIRSTTERM">widtools</I>. The first two of these no longer seem to be maintained. Fortunately, it is still possible to obtain <ICLASS="FIRSTTERM">widtools</I> <AHREF="http://www.batse.msfc.nasa.gov/~mallozzi/home/software/xforms/src/widtools-2.0.tgz"TARGET="_top">here</A>. </P><DIVCLASS="CAUTION"><TABLECLASS="CAUTION"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/caution.png"HSPACE="5"ALT="Caution"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>The <ICLASS="FIRSTTERM">widtools</I> (widget tools) package requires the <ICLASS="FIRSTTERM">XForms</I> library to be installed. Additionally, the <AHREF="filearchiv.html#MAKEFILEREF">Makefile</A> needs some judicious editing before the package will build on a typical Linux system. Finally, three of the six widgets offered do not work (and, in fact, segfault).</P></TD></TR></TABLE></DIV><P><ANAME="DIALOGREF"></A></P><P>The <ICLASS="FIRSTTERM">dialog</I> family of tools offers a method of calling <SPANCLASS="QUOTE">"dialog"</SPAN> widgets from a shell script. The original <ICLASS="FIRSTTERM">dialog</I> utility works in a text console, but its successors, <ICLASS="FIRSTTERM">gdialog</I>, <ICLASS="FIRSTTERM">Xdialog</I>, and <ICLASS="FIRSTTERM">kdialog</I> use X-Windows-based widget sets.</P><DIVCLASS="EXAMPLE"><HR><ANAME="DIALOG"></A><P><B>Example 33-19. Widgets invoked from a shell script</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # dialog.sh: Using 'gdialog' widgets. 3 4 # Must have 'gdialog' installed on your system to run this script. 5 # Or, you can replace all instance of 'gdialog' below with 'kdialog' ... 6 # Version 1.1 (corrected 04/05/05) 7 8 # This script was inspired by the following article. 9 # "Scripting for X Productivity," by Marco Fioretti, 10 # LINUX JOURNAL, Issue 113, September 2003, pp. 86-9. 11 # Thank you, all you good people at LJ. 12 13 14 # Input error in dialog box. 15 E_INPUT=65 16 # Dimensions of display, input widgets. 17 HEIGHT=50 18 WIDTH=60 19 20 # Output file name (constructed out of script name). 21 OUTFILE=$0.output 22 23 # Display this script in a text widget. 24 gdialog --title "Displaying: $0" --textbox $0 $HEIGHT $WIDTH 25 26 27 28 # Now, we'll try saving input in a file. 29 echo -n "VARIABLE=" > $OUTFILE 30 gdialog --title "User Input" --inputbox "Enter variable, please:" \ 31 $HEIGHT $WIDTH 2>> $OUTFILE 32 33 34 if [ "$?" -eq 0 ] 35 # It's good practice to check exit status. 36 then 37 echo "Executed \"dialog box\" without errors." 38 else 39 echo "Error(s) in \"dialog box\" execution." 40 # Or, clicked on "Cancel", instead of "OK" button. 41 rm $OUTFILE 42 exit $E_INPUT 43 fi 44 45 46 47 # Now, we'll retrieve and display the saved variable. 48 . $OUTFILE # 'Source' the saved file. 49 echo "The variable input in the \"input box\" was: "$VARIABLE"" 50 51 52 rm $OUTFILE # Clean up by removing the temp file. 53 # Some applications may need to retain this file. 54 55 exit $? 56 57 # Exercise: Rewrite this script using the 'zenity' widget set.</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="XMESSAGEREF2"></A> The <AHREF="extmisc.html#XMESSAGEREF">xmessage</A> command is a simple method of popping up a message/query window. For example: <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 xmessage Fatal error in script! -button exit</PRE></TD></TR></TABLE> </P><P><ANAME="ZENITYREF2"></A> The latest entry in the widget sweepstakes is <AHREF="extmisc.html#ZENITYREF">zenity</A>. This utility pops up <ICLASS="FIRSTTERM">GTK+</I> dialog widgets-and-windows, and it works very nicely within a script. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 get_info () 2 { 3 zenity --entry # Pops up query window . . . 4 #+ and prints user entry to stdout. 5 6 # Also try the --calendar and --scale options. 7 } 8 9 answer=$( get_info ) # Capture stdout in $answer variable. 10 11 echo "User entered: "$answer""</PRE></TD></TR></TABLE> </P><P>For other methods of scripting with widgets, try <ICLASS="FIRSTTERM">Tk</I> or <ICLASS="FIRSTTERM">wish</I> (<ICLASS="FIRSTTERM">Tcl</I> derivatives), <ICLASS="FIRSTTERM">PerlTk</I> (<ICLASS="FIRSTTERM">Perl</I> with <ICLASS="FIRSTTERM">Tk</I> extensions), <ICLASS="FIRSTTERM">tksh</I> (<ICLASS="FIRSTTERM">ksh</I> with <ICLASS="FIRSTTERM">Tk</I> extensions), <ICLASS="FIRSTTERM">XForms4Perl</I> (<ICLASS="FIRSTTERM">Perl</I> with <ICLASS="FIRSTTERM">XForms</I> extensions), <ICLASS="FIRSTTERM">Gtk-Perl</I> (<ICLASS="FIRSTTERM">Perl</I> with <ICLASS="FIRSTTERM">Gtk</I> extensions), or <ICLASS="FIRSTTERM">PyQt</I> (<ICLASS="FIRSTTERM">Python</I> with <ICLASS="FIRSTTERM">Qt</I> extensions).</P></DIV></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="optimizations.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="securityissues.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Optimizations</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="miscellany.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Security Issues</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -