![引数を使用して複数のディレクトリでbashスクリプトを実行するには? [コピー]](https://linux33.com/image/166533/%E5%BC%95%E6%95%B0%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E8%A4%87%E6%95%B0%E3%81%AE%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%A7bash%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF%EF%BC%9F%20%5B%E3%82%B3%E3%83%94%E3%83%BC%5D.png)
答え1
(追加の説明がないため、質問のタイトルの「引数」を無視してください。)スクリプトがapp1.sh
現在のディレクトリにあり、現在のディレクトリ内のすべてのディレクトリとサブディレクトリでこのスクリプトを実行するとします。
shopt -s globstar nullglob dotglob
runme=$PWD/app1.sh
for folder in ./**/; do
( cd "$folder" && "$runme" )
done
**
ワイルドカードモード(シェルオプションで有効)を使用してglobstar
すべてのディレクトリを見つけます。その後、これらのディレクトリを繰り返し、cd
各ディレクトリのディレクトリ変更を使用して、そのディレクトリを現在の作業ディレクトリとして使用してスクリプトを実行します。
サブディレクトリではなく最上位ディレクトリのみを処理するには、削除しますglobdot
。./**/
./*/
nullglob
パターンが一致しない場合(ディレクトリなし)、ループをまったく実行しないようにシェルオプションが設定され、隠されたディレクトリも一致するようにシェルdotglob
オプションが設定されます。
ループ本体の周りの括弧は、コマンドをサブシェルで囲みます。現在の作業ディレクトリはサブシェルに対してローカルなので、cd
スクリプトを実行した後に「再び終了」する必要はありません。
使用find
:
runme=$PWD/app1.sh
find . -type d -exec sh -c '
runme=$1; shift
for folder do
( cd "$folder" && "$runme" )
done' sh "$runme" {} +
これは同じことを行います(ほぼ;これはディレクトリへのシンボリックリンクをチェックしません。現在の目次)。見つかったディレクトリ配置の場合は、短いインラインシェルスクリプトを呼び出します。スクリプトは実行するスクリプトのパス名を選択し、残りの引数(見つかったディレクトリ)を繰り返し、そのディレクトリに変更してスクリプトを実行します。
サブディレクトリではなく最上位ディレクトリのみを処理するには、-maxdepth 1
次のコマンドにテストを追加しますfind
。
find . -maxdepth 1 ...as before...
現在のディレクトリを処理したくない場合は、上記と同様にコマンドにまたは-mindepth 1
を追加してください。別の方法は、現在のディレクトリ内のすべてのディレクトリを検索パスとして-name . -prune -o
使用することです。ただし、次の場合、「パラメータのリストが多すぎます」エラーが原因で失敗します。find ./*/ ...
数千現在のディレクトリ内のディレクトリ(これらの最上位ディレクトリが必要な場合-maxdepth 1
でも変更する必要がありますが、正直なところ、この場合は通常のシェルループを使用します)。-maxdepth 0
-mindepth
非標準テストですが、-maxdepth
一般的に実装されています。
関連:
答え2
find
以下を使用してこれを実行できます-type d
。
$ PWD=$(pwd); SCRIPT=/full/path/to/script.sh; find . -type d -exec bash -c "cd {}; $SCRIPT; cd $PWD" ";"
一度だけ使用すると-execdir
避けられますcd $PWD
。
$ SCRIPT=/full/path/to/script.sh; find . -type d -execdir bash -c "cd {}; $SCRIPT" ";"