重要:あなたが常には、コマンドが失敗したかどうかを判断するために、Perlのsystem
関数からの戻り値をチェックする必要があります。
float値のフォーマットには、次のコードのようにPerlのsprintf
を使用します。はい、フォーマット指定子としてコマンドを使用することで逃げることができますが、コマンドの%文字が他の場所にあると驚くべき結果になる可能性があります。 2つのステップを使用する方が安全です。場合
#! /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";
のために一緒に実行している2つのプログラムの出力をスタンドインを使用して用語に関して
[1.000000e+05][string]
[3.141590e+00][string]
[2.718280e+00][string]
で、システムコールのための低レベルの要求を指しオペレーティングシステムからのサービス,open
,close
,unlink
などが挙げられる。 Perlのシステム関数はシステムコールを使用しますが、2つの概念は区別されます。
実際にはであることを確認してください。シェルがコマンドライン引数を無視しないようにするには、“Safe Pipe Opens” section of perlipcに記載されている方法を使用してください。 Perlのsystem
とexec
関数は、コマンド全体を含む単一の文字列ではなく、引数のリストが与えられたときにシェルをバイパスします。
標準出力をリダイレクトしたいので状況が少し複雑です。以下のコードは子をフォークし、子のSTDOUT
をoutfile.out
に追加するように設定してから、fermion
を子の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: $!";
}
}
「システムリスト」または「システム{プログラム名}リスト[呼び出し]」(http://perldoc.perl.org/functions/system.html)をご検討ください。いつか、多くのリファクタ、 '$ arg2'が' 'rm -rf /' 'になると、もっと安全になります。シェル出力のリダイレクトを使用することはできませんが、 'outfile.out'を自分で開き、STDOUTにdupするか、シェルスクリプト内の'。/ fermions'をラップして出力をキャプチャすることができます。 – pilcrow
。私はこれについて私のコードを修正するが、私は、この時点で、将来の使用のためにこの質問をしている。 –