このエラーが発生する理由は、make (特に GNU make) が多くの最適化を実行しようとするためです。それらの 1 つは、コマンドがシェルを必要としない単純なコマンドのように見える場合、make は fork/exec を介して直接コマンドを呼び出し、シェルを実行しないことです。コマンドがシェルの組み込みとしてのみ存在する場合、これは機能しません。コマンドラインulimit -c 10000
は単純なコマンドであり、ulimit は make が認識しているシェル組み込みだけとして定義されていないため、make はulimit
直接 fork/exec を試みます。したがって、差し迫った問題を回避する方法は、シェルに特別な文字を追加するだけです (最も明白なものは です;
)。これにより、このコマンドをシェルに送信する必要があることが示唆されます。
ただし、これはうまくいきません。
上記の H2CO3 のコメントとは正反対です:それが提供する機能を考えると、[シェルの組み込み] である可能性はありますか? あなたが自問しなければならない本当の質問は反対です:それが提供する機能を考えると、どうしてそれがそうではないでしょうか? ulimit のマニュアル ページには次のように明確に記載されています。シェルレギュラービルトイン。
UNIX のプロセスがその親プロセスのどの側面も変更することは事実上不可能であることを覚えておく必要があります。それ自体、または呼び出す子プロセスのみを変更できます。これには、環境変数、作業ディレクトリが含まれ、ulimit 設定も含まれます。
では、これはあなたの状況にどのように当てはまりますか? make レシピの各論理行は個別のシェルで呼び出されることを覚えておく必要があります。したがって、次のようなコマンドの場合:
core: myprogram
ulimit -c 10000 ;
./myprogram
ulimit -c 0 ;
(セミコロンを追加してシェルを強制します) make が基本的に呼び出すのは次のとおりです。
core: myprogram
/bin/sh -c 'ulimit -c 10000 ;'
/bin/sh -c './myprogram'
/bin/sh -c 'ulimit -c 0 ;'
ご覧のとおり、各 ulimit は独自のシェルで呼び出されるため、事実上役に立ちません。そのシェルのコアファイルサイズ制限を変更し、シェルが終了して変更が失われ、プログラムが元の ulimit を使用して新しいシェルで呼び出され、次に 3 番目のシェルが呼び出され、コアの ulimit が 0 に設定されます。 (これも駄目)。
次のように、これらすべてのコマンドを単一の論理行に配置する必要があります。
core: myprogram
ulimit -c 10000; ./myprogram
(シェルはとにかく終了するので、制限を元に戻す必要はありません)。
補足として、これが make がこれらのシェル組み込み関数についてあまり気にしない理由です。このようなビルトインは、セミコロンなどの特殊なシェル文字を使用する必要がないコンテキストでは、基本的に使用できません。