4

-Iスイッチを使用せずに、サンドボックスベースディレクトリに関連するファイルをm4テキスト内に含めたい。

これまで、sys呼び出しを使用して環境変数を取得する方法を理解しました。

define(MODEL_ROOT,`syscmd(`printf $MODEL_ROOT')')dnl

次に、その環境変数に基づいたファイルを含めたいと思います。

include(MODEL_ROOT/sw/lib/m4_macros/foreach2.m4)

合計で、私は持っています:

define(MODEL_ROOT,`syscmd(`printf $MODEL_ROOT')')

MODEL_ROOT

MODEL_ROOT/sw/lib/m4_macros/foreach2.m4

include(MODEL_ROOT/sw/lib/m4_macros/foreach2.m4)

どの印刷物:

/home/ross/sandbox

/home/ross/sandbox/sw/lib/m4_macros/foreach2.m4

/home/ross/sandboxforeach_example.m4:7: m4: Cannot open /sw/lib/m4_macros/foreach2.m4: No such file or directory

includeの通常の構文は次のとおりです。

include(`file.m4')

しかし、引用するMODEL_ROOT/sw/lib/m4_macros/foreach2.m4と、m4は次のようになります。

[...]
include(`MODEL_ROOT/sw/lib/m4_macros/foreach2.m4')

m4は文句を言う:

[...]
foreach_example.m4:7: m4: Cannot open MODEL_ROOT/sw/lib/m4_macros/foreach2.m4: No such file or directory

パスに環境変数を含むファイルを含めるにはどうすればよいですか?

4

2 に答える 2

4

esyscmdの代わりに使用する必要があると思いますsyscmdesyscmdコマンドライン出力を読み取ります。

于 2011-03-17T23:31:03.220 に答える
1

他の回答が述べているesyscmdように、コマンドの出力を取得できるようにするには、GNU拡張機能を使用する必要があります。マクロは、すべてのsyscmdマクロとdivertsを無視して、stdoutに直接出力します。

それが他のどこでも機能しているように見えた理由MODEL_ROOTです。それは、m4がその出力を処理する必要がなかった非常に単純な状況でのみ機能していました。

ただし、引用に関して:

  • include(MODEL_ROOT/sw/lib/m4_macros/foreach2.m4)
  • include(`MODEL_ROOT/sw/lib/m4_macros/foreach2.m4')

これにより、引用符が移動するはずです。

include(MODEL_ROOT`/sw/lib/m4_macros/foreach2.m4')

引用符はマクロの展開を妨げるため、MODEL_ROOTここ(展開したい場所)でマクロを囲んではなりません。文字列の残りの部分を引用するのは「適切」です。これは、マクロによって拡張したいものではないためです。


余談ですが、シェルから環境変数を取得するためのより堅牢な方法は、次のようになります。

define(`HOME', esyscmd(`printf \`\`%s\'\' "$HOME"'))

これにより、マクロ名、パーセント記号、円記号、グロブ文字、または環境変数の値の空白によって引き起こされる問題を回避できます。これとソリューションの唯一の違いは\`\`%s\'\'、変数の前後に引用符を追加することです。

注意:esyscmd出力は常にマクロとして展開されるため、真にサニタイズされた状態を維持するのは難しい場合があります。上記の引用記号を使用していますが、それらの引用記号が環境変数に存在する場合は、引き続きトリップします。

于 2016-08-01T08:45:47.820 に答える