外部コマンドを安全に実行

back
system または exec に、引数をリストで渡して実行する。

system("find", "/etc", "-name", $ARGV[0]);

これでシェルを使わずに実行されるので、
外部入力値などの "; rm -rf /" などの入力・実行ができなくなる。

ただし、外部コマンドの実行側では、コマンドの終了ステータスしか
取得できない(system, exec の戻り値はコマンドの exit 値 * 256)
(また、">" を使ったリダイレクトもできない)ので、
外部コマンドの標準入出力を操作したい場合は以下のようにやる。


# $command の標準出力を受け取る

$pid = open(EXE, "-|");
if ($pid == 0) {
  exec($command, @arguments);
}
elsif (defined $pid) {
  while (<EXE>) {
    # $_ に結果が1行ずつ
  }
  close(EXE);
}
else {
  die "fork failed: $!";
}


(入力値チェックを行わないまま)open や back-tick を使うのは論外

back