私のビルドファイル:
all: ...(other rules) clean
clean:
rm $(find . -type f -executable)
clean
上記のMakefileからルールを削除すると、すべてが期待どおりに機能します。追加されるとmake
(またmake clean
)コマンドの結果は次のようになります。
rm
rm: missing operand
Try 'rm --help' for more information.
make: *** [Makefile:46: clean] Error 1
ここで問題の原因は何ですか?解決策は何ですか?
ベストアンサー1
いくつかの質問があります。
Makefileの$記号をシェルに渡す
コマンドを実行したい
rm $(find . -type f -executable)
シェルにコマンド置換を実行させます。これを行うには、以下を作成する必要があります。
clean:
rm $$(find . -type f -executable)
で使用するドルだけそれ自体を倍増します$
。
「整理」するものがない状況処理
出力が空find
の場合、コマンド置換後
rm $(find . -type f -executable)
~になる
rm
一般的なrm
コマンドは、何を削除するかを教えていないと文句を言います。この問題を解決する1つの方法は、を使用してxargs
出力を処理することですfind
。出力があるfind
場合、出力がある場合はそれをチャンクに分割してrmを実行します。
clean:
find . -type f -executable | xargs rm
ファイル名のランダムな文字処理
Unixファイル名は、文字で区切られたコンポーネントで構成されています/
。コンポーネント自体は、/
NULとNULを除く任意の文字シーケンスです。特にコンポーネントには、改行、スペース、タブなどを含めることができます*
。
コマンド置換()の場合、rm $(find . -type f -executable)
シェルはfindの出力を処理します。そのため、空白文字によって単語分割が発生し、*
文字によってファイル名「globbing」が発生するなどの現象が発生する。合理的な実装のためには、xargs
このような状況を避ける必要があります。
ファイル名がthenで始まる場合は、-
コマンドrm
のオプションとして扱うことができます。これを防ぐ簡単な方法は、--
「オプションの終わり」を表示するコマンドを追加することです。
残りの主な問題は改行です。入力を改行文字に分割します。したがって、呼び出されたファイルがxargs
ある場合、出力はabc\ndef
find
abc
def
xargs
2つのファイルrm
名abc
とdef
。
この問題を解決するには、改行文字の代わりにファイル名に表示できない1文字(NUL)を区切り文字として指定して使用しますfind
。xargs
clean:
find . -type f -executable -print0 | xargs -0 rm --
find
あなたがサポートしている場合最高のソリューション
clean:
find . -type f -executable -delete
ここで削除されたファイルを直接見つけることができます(存在する場合)。追加プロセスを開始する必要がないため、より効率的です。シェルや xargs プロセスにエスケープ文字は必要ありません。make
何をすべきかを示す特別な文字はありません。 「削除するファイルがありません」状況を正しく処理します。