📄 ch14_01.htm
字号:
here are meant for the shell and not for Perl. Double quotes would
have permitted Perl to expand <tt class="literal">$i</tt> to its current
Perl value, and not let the shell expand it to its own
value.<a href="#FOOTNOTE-309">[309]</a> By the way, that little shell script
goes through all of the normal files in the current directory,
printing out each one's name and contents; you can try it out
yourself if you don't believe us.
</p><blockquote class="footnote"> <a name="FOOTNOTE-309" /></a><p>[309]Of course, if you set <tt class="literal">$i =
'$i'</tt>, then it would work anyway, until a maintenance
programmer came along and "fixed" that line out of
existence. </p> </blockquote>
<a name="lperl3-CHP-14-SECT-1.1" /></a><div class="sect2">
<h3 class="sect2">14.1.1. Avoiding the Shell</h3>
<p>The system operator may also be invoked with more than one
argument,<a href="#FOOTNOTE-310">[310]</a> in which
case a shell doesn't get involved, no matter how complicated
the text:
</p><blockquote class="footnote"> <a name="FOOTNOTE-310" /></a><p>[310]Or with a parameter in the indirect-object
slot, like <tt class="literal">system { 'fred' }
'barney';</tt>, which runs the program
<tt class="literal">barney</tt>, but lies to it so it thinks that
it's called <tt class="literal">'fred'</tt>. See the
<em class="emphasis">perlfunc</em> manpage.</p> </blockquote>
<blockquote><pre class="code">my $tarfile = "something*wicked.tar";
my @dirs = qw(fred|flintstone <barney&rubble> betty );
system "tar", "cvf", $tarfile, @dirs;</pre></blockquote>
<p>In this case, the first parameter (<tt class="literal">"tar"</tt> here)
gives the name of a command found in the normal
<tt class="literal">PATH</tt>-searching way, while the remaining arguments
are passed, one by one, directly to that command. Even if the
arguments have <a name="INDEX-957" /></a>shell-significant characters, such as
the name in <tt class="literal">$tarfile</tt> or the directory names in
<tt class="literal">@dirs</tt>, the shell never gets a chance to mangle the
string. So that <tt class="literal">tar</tt> command will get precisely
five parameters. Compare this with:
</p>
<blockquote><pre class="code">system "tar cvf $tarfile @dirs"; # Oops!</pre></blockquote>
<p>Here, we've now piped a bunch of stuff into a
<i class="command">flintstone</i> command and put it into the background,
and opened <em class="filename">betty</em> for output.
</p>
<p>And that's a bit scary,<a href="#FOOTNOTE-311">[311]</a> especially if those variables are from
user input -- such as from a web form or something. So, if you
<em class="emphasis">can</em> arrange things so that you can use the
multiple-argument version of <tt class="literal">system</tt>, you
probably should use that way to launch your subprocess. (You'll
have to give up the ability to have the shell do the work for you to
set up I/O redirection, background processes, and the like, though.
There's no such thing as a free launch.)
</p><blockquote class="footnote"> <a name="FOOTNOTE-311" /></a><p>[311]Unless you're
using taint checking and have done all the right things to prescan
your data to ensure that the user isn't trying to pull a fast
one on you.</p> </blockquote>
<p>Note that redundantly, a single argument invocation of
<tt class="literal">system</tt> is nearly equivalent to the proper
multiple-argument version of <tt class="literal">system</tt>:
</p>
<blockquote><pre class="code">system $command_line;
system "/bin/sh", "-c", $command_line;</pre></blockquote>
<p>But nobody writes the latter, unless you want things to be processed
by a different shell, like the C-shell:
</p>
<blockquote><pre class="code">system "/bin/csh", "-fc", $command_line;</pre></blockquote>
<p>Even this is pretty rare, since the One True Shell<a href="#FOOTNOTE-312">[312]</a> seems to have a lot more flexibility,
especially for scripted items.
</p><blockquote class="footnote">
<a name="FOOTNOTE-312" /></a><p>[312]That's <em class="emphasis">/bin/sh</em>, or whatever your
Unix system has installed as the most Bourne-like shell. If you
don't have a One True Shell, Perl figures out how to invoke
some other command-line interpreter, with notable
consequences -- noted, that is, in the documentation for that Perl
port.</p> </blockquote>
<p>The return value of the system operator is based upon the exit status
of the child command<a href="#FOOTNOTE-313">[313]</a>. In Unix, an exit value of <tt class="literal">0</tt> means
that everything is OK, and a non-zero exit value usually indicates
that something went wrong:
</p><blockquote class="footnote"> <a name="FOOTNOTE-313" /></a><p>[313]It's actually the
"wait" status, which is the child exit code times 256,
plus 128 if core was dumped, plus the signal number triggering
termination, if any. But we rarely check the specifics of that, and a
simple true/false value suffices for nearly all applications.</p>
</blockquote>
<blockquote><pre class="code">unless (system "date") {
# Return was zero - meaning success
print "We gave you a date, OK!\n";
}</pre></blockquote>
<p>Note that this is backward from the normal "true is
good -- false is bad" strategy for most of the operators, so
to write a typical "do this or die" style, we'll
need to flip false and true. The easiest way is to simply prefix the
<tt class="literal">system</tt> operator with a bang (the logical-not
operator):
</p>
<blockquote><pre class="code">!system "rm -rf files_to_delete" or die "something went wrong";</pre></blockquote>
<p>In this case, including <tt class="literal">$!</tt> in the error message
would not be appropriate, because the failure is most likely
somewhere within the experience of the <i class="command">rm</i> command,
and it's not a system-call related error within Perl that
<tt class="literal">$!</tt> can reveal.<a name="INDEX-958" /></a>
</p>
</div>
</div>
<hr width="684" align="left" />
<div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch13_09.htm"><img alt="Previous" border="0" src="../gifs/txtpreva.gif" /></a></td><td align="center" valign="top" width="228"><a href="index.htm"><img alt="Home" border="0" src="../gifs/txthome.gif" /></a></td><td align="right" valign="top" width="228"><a href="ch14_02.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr><tr><td align="left" valign="top" width="228">13.9. Exercises</td><td align="center" valign="top" width="228"><a href="index/index.htm"><img alt="Book Index" border="0" src="../gifs/index.gif" /></a></td><td align="right" valign="top" width="228">14.2. The exec Function</td></tr></table></div>
<hr width="684" align="left" />
<img alt="Library Navigation Links" border="0" src="../gifs/navbar.gif" usemap="#library-map" />
<p><p><font size="-1"><a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font></p>
<map name="library-map"><area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -