在我的Perl程序中,我正在尝试使用system
运行用C编写的另一个命令。该命令需要几个参数:字符串,浮点数,两个整数,一对浮点数和另一个字符串。我正在运行这个
my $arg1="electron";
my $arg2=0.511;
# more definitions
system("./fermions $arg1 $arg2 $arg3 $arg4 " .
"$arg5 $arg6 \"string\" > outfile.out");
我需要将$arg5
变为几个不同的浮点值。我通过设置$arg5="1.0e5"
然后在for循环中运行if语句来将其更改为字符串。我希望能够以浮动方式执行此操作,并尝试
system("./fermions $arg1 $arg2 $arg3 $arg4 " .
"%e $arg6 \"string\" >outfile.out",
$arg5);
但这不起作用。还有另一种选择,或者我的if语句选项是唯一的吗?
答案 0 :(得分:6)
如果要使用printf表示法(如“%e”),则需要使用Perl sprintf
内置函数。否则你最终会将“%e”作为文字参数传递。
答案 1 :(得分:1)
重要提示:您应始终检查Perl system
函数的返回值,以确定命令是否失败。
使用Perl的sprintf
格式化浮点值,如下面的代码所示。是的,您可以使用该命令作为格式说明符,但如果该命令在其他地方有杂散的%字符,则可能会得到令人惊讶的结果。使用两个步骤更安全。
#! /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][string] [3.141590e+00][string] [2.718280e+00][string]
关于术语,系统调用是指来自操作系统的低级服务请求,例如,open
,close
,{{1} }, 等等。虽然Perl的系统函数使用系统调用,但这两个概念是截然不同的。
要使shell真正安全安全,而不是捏造命令行参数,请使用“Safe Pipe Opens” section of perlipc中描述的技术。 Perl的system
和exec
函数在给定参数列表时绕过shell,而不是包含整个命令的单个字符串。
您的情况有点棘手,因为您想重定向标准输出。下面的代码会分叉一个孩子,将孩子的unlink
设置为附加到STDOUT
,然后在孩子中使用exec
运行outfile.out
。父母等待孩子退出并报告任何失败。
fermion