重要提示:您应该始终检查 Perlsystem
函数的返回值以确定命令是否失败。
使用 Perlsprintf
来格式化浮点值,如下面的代码所示。是的,您可以不使用该命令作为格式说明符,但如果该命令在其他地方有杂散的 % 字符,您可能会得到令人惊讶的结果。使用两个步骤更安全。
#! /usr/bin/env perl
use strict;
use warnings;
my @float_values = (1.0e5, 3.14159, 2.71828);
for my $f (@float_values) {
my $arg5 = sprintf "%e", $f;
system(qq[./fermions $arg5 "string" >> outfile.out]) == 0
or warn "$0: fermions failed";
}
如果您不熟悉语法,qq[...]
它就像双引号字符串一样工作,但不同的分隔符意味着您不必在命令中转义双引号。
请注意,出于印刷目的,我省略了其他参数,但您可以将它们与$arg5
. 另一个微妙的变化是切换到>>
追加而不是>
破坏。
使用替身fermions
#! /usr/bin/env perl
$" = "][";
warn "[@ARGV]\n";
两个程序一起运行的输出是
[1.000000e+05][字符串]
[3.141590e+00][字符串]
[2.718280e+00][字符串]
就术语而言,系统调用是指来自操作系统的低级服务请求,例如、open
、close
、unlink
等等。尽管 Perl 的系统函数使用系统调用,但这两个概念是不同的。
为了确保 shell不会伪造你的命令行参数,请使用perlipc 的“安全管道打开”部分中描述的技术。当给定参数列表而不是包含整个命令的单个字符串时,Perlsystem
和函数会绕过 shell。exec
您的情况有点棘手,因为您想重定向标准输出。下面的代码 fork 一个孩子,将孩子设置STDOUT
为 append outfile.out
,然后在孩子中运行fermion
with exec
。父母等待孩子退出并报告任何失败。
#! /usr/bin/env perl
use strict;
use warnings;
my @float_values = (1.0e5, 3.14159, 2.71828);
for my $f (@float_values) {
my $arg5 = sprintf "%e", $f;
my $pid = fork;
if (defined $pid) {
if ($pid == 0) {
my $path = "outfile.out";
open STDOUT, ">>", $path or die "$0: open $path: $!";
exec "./fermions", $arg5, "string" or die "$0: exec: $!";
}
else {
local $!;
my $pid = waitpid $pid, 0;
warn "$0: waitpid: $!" if $pid == -1 && $!;
warn "$0: fermion exited " . ($? >> 8) if $?;
}
}
else {
die "$0: fork: $!";
}
}