如何使用科学记数法制作Perl的system()格式参数?

时间:2012-04-21 02:26:27

标签: perl floating-point scientific-notation

在我的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语句选项是唯一的吗?

2 个答案:

答案 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]

关于术语,系统调用是指来自操作系统的低级服务请求,例如openclose,{{1} }, 等等。虽然Perl的系统函数使用系统调用,但这两个概念是截然不同的。

要使shell真正安全安全,而不是捏造命令行参数,请使用“Safe Pipe Opens” section of perlipc中描述的技术。 Perl的systemexec函数在给定参数列表时绕过shell,而不是包含整个命令的单个字符串。

您的情况有点棘手,因为您想重定向标准输出。下面的代码会分叉一个孩子,将孩子的unlink设置为附加到STDOUT,然后在孩子中使用exec运行outfile.out。父母等待孩子退出并报告任何失败。

fermion