Makefileを含む複数のディレクトリがあります。
Makefileが存在する場合は、それを実行するためにこのスクリプトを作成しました。
find . -name "Makefile" -exec sh -c 'make re -C "$1" $(dirname "$0")' {} \;
しかし、うまくいかないようです。次のエラーが発生します。
make: the `-C' option requires a non-empty string argument
Usage: make [options] [target] ...
Options:
-b, -m Ignored for compatibility.
-B, --always-make Unconditionally make all targets.
-C DIRECTORY, --directory=DIRECTORY
[...]
しかし、ormake re -C
と交換するとうまくいきます...echo
printf
find . -name "Makefile" -exec sh -c 'printf "%s\n" "$1" $(dirname "$0")' {} \;
# or
find . -name "Makefile" -exec sh -c 'echo "$1" $(dirname "$0")' {} \;
答え1
元のコードは2つのパラメータとを$0
使用します$1
が、何かを渡すだけで空白のままにし$0
ます$1
。これはmake
行動方法について不平を言うかもしれません。
あなたできる必要に応じて、"$1"
オペランドとオプションの順序が混在していても構いません。コマンドから単に削除してコマンドの置き換えを引用してこの問題を解決できますが、いくつかの異なるアイデアを提供します。よく。dirname
make
次の2つのコマンドは、Makefile
現在のディレクトリまたはその下で呼び出されているすべての一般的なファイルを検索し、そのファイルがmake -C
存在する各ディレクトリにターゲットを作成するために使用されます。re
find . -name Makefile -type f -exec sh -c 'make -C "${1%/*}" re' sh {} \;
または
find . -name Makefile -type f -exec sh -c '
for pathname do
make -C "${pathname%/*}" re
done' sh {} +
2番目のコマンドでは、sh -c
単一の名前の代わりに見つかったパス名をできるだけ繰り返すようにスクリプトを変更しました。
私はdirname
両方のコマンドを標準の引数拡張に置き換えました$pathname
。一つファイルが現在のディレクトリにある場合でも、パスMakefile
名にはスラッシュが含まれているので安全です。いいえdirname
より速い選択肢に変更したいです。
そのオプションと連携しないmake
より速いバリエーションは、-C
次の(非標準)述語を使用して実行することです。make
-execdir
find
find . -name Makefile -type f -execdir make re \;
これにより、find
作業ディレクトリがmake
ファイルのあるディレクトリに変更されます。Makefile
この変形の利点は、スクリプトをmake
処理せずに直接実行されることです。sh -c
答え2
それを使用するよりもmake -C
ただディレクトリに入る方が簡単です。cd
この実装はうまく動作します。
find . -name "Makefile" -exec sh -c 'cd "$(dirname "$0")" && make re' {} \;