インストール済みのプログラムを呼び出して、ファイルを1つずつ実行するスクリプトを作成しました。同じプログラムがprocheck abc.pdb
のようにターミナルから実行されている場合、正常に動作しています。しかし、このプログラムを次のようなPerlスクリプトで実行すると
#!/usr/bin/Perl -w
@proc = glob '*.pdb';
foreach $proc (@proc)
{
system ('procheck $proc 2.0');
}
エラーが発生する
sh: 1: procheck: not found
ここで問題になる可能性のあることが2つあります。まず、単一引用符で囲まれた文字列では、変数は展開されないため、system()
呼び出しはリテラル文字列_procheck $proc 2.0
_を参照します。シェルに特殊な文字(_$
_)が含まれているため、Perlはシェルを介してコマンドを実行し、シェルはそれを拡張する機会を得ます。環境に変数proc
が含まれていない限り、何も展開されません。しかし、シェルはprocheck
内にプログラムPATH
を見つけることすらできないので、それはそれほど重要ではありません。それについて不満を言う。
引用符を二重引用符に変更すると、Perlによって変数が展開されます(ループ内でその変数を使用しているので、これはおそらく望んでいることです)。しかし、そうすると、おそらくprocheck
が見つからないという警告がPerlから出されます。
これに対する解決策は、プログラムへの完全なパスを与えるか、それがスクリプトPATH
にあることを確認することです。
インタラクティブシェルで実行すると機能する場合でも、procheck
が実際にはエイリアスまたは関数である可能性があります。通常の実行可能ファイルの場合は、PATH
にあり、Perlとサブシェルに継承する必要があります。たとえばバッシュ、_type -a procheck
_を使用して、実際に何が実行されているかを確認したり、エイリアスの背後にマスクされたディスクファイルのような他の選択肢があるかどうかを確認したりできます。
また、コマンドの実行時にシェルが必要ない場合は、system
のリスト形式を使用して、system
への個別の引数としてコマンドに引数を指定することで、Perlが誤ってそれを呼び出すことを防ぐことができます。ここでは、system("procheck", $proc, "2.0")
になります。
問題は、単一引用符を使用していることです。
代わりにこれを試してください...
system ("procheck $proc 2.0");