web-dev-qa-db-ja.com

sh:1:プログラムが見つかりません

インストール済みのプログラムを呼び出して、ファイルを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 
1
s kumar

ここで問題になる可能性のあることが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")になります。

2
ilkkachu

問題は、単一引用符を使用していることです。

代わりにこれを試してください...

system ("procheck $proc 2.0");
0
David Favor