多くの単一レベルのサブディレクトリを持つ特定のディレクトリで実行されるスクリプトを記述しようとしています。スクリプトは各サブディレクトリにcdし、ディレクトリ内のファイルに対してコマンドを実行し、cdアウトして次のディレクトリに進みます。これを行う最良の方法は何ですか?
多くの単一レベルのサブディレクトリを持つ特定のディレクトリで実行されるスクリプトを記述しようとしています。スクリプトは各サブディレクトリにcdし、ディレクトリ内のファイルに対してコマンドを実行し、cdアウトして次のディレクトリに進みます。これを行う最良の方法は何ですか?
回答:
for d in ./*/ ; do (cd "$d" && somecommand); done
for d in ./*/ ; do (cd "$d" && ls); done
機能します: は機能しません。しかし、for d in ./*/ ; do (cd "$d" && for d in ./*/ ; do (cd "$d" && ls); done ); done
動作します。-この例では、lsをコマンドとして使用しています。
-bash: cd: ./*/: No such file or directory
最善の方法は、まったく使用cd
しないことです。
find some/dir -type f -execdir somecommand {} \;
execdir
はのようなものexec
ですが、作業ディレクトリは異なります:
-execdir command {} [;|+]
Like -exec, but the specified command is run from the
subdirectory containing the matched file, which is not normally
the directory in which you started find. This a much more
secure method for invoking commands, as it avoids race
conditions during resolution of the paths to the matched files.
POSIXではありません。
find
これらのコマンドを実行するので、エイリアスを認識しません。ディレクトリmd
とは何.link
ですか?
bash
:find . -type f -iname '*.link' -execdir ${BASH_ALIASES[md]} -i {} \;
あなたは何をする必要はありませんcat
しwget
ていた、-i
ファイルからURLを読み込むためのフラグを。また、これは元の質問とは多少異なります(名前が付けられたファイルのみに関心.link
があり、存在する可能性のある他のファイルには関心がないようです)。
cd -P .
for dir in ./*/
do cd -P "$dir" ||continue
printf %s\\n "$PWD" >&2
command && cd "$OLDPWD" ||
! break; done || ! cd - >&2
上記のコマンドは、任意のサブシェルを行う必要はありません-それだけの交流により、現在のシェル内でその進捗状況を追跡$OLDPWD
して$PWD
。cd -
シェルがディレクトリを変更するとき、基本的にこれらの2つの変数の値を交換するとき。また、stderrで機能する各ディレクトリの名前も出力します。
私はそれをもう一度見て、エラー処理でより良い仕事をすることができると決めました。これは、その中にそれができないディレクトリをスキップしますcd
-とcd
stderrに理由に関するメッセージを出力します-そしてそれは意志break
あなたの場合/ゼロ以外の終了コードW command
正常に実行しない場合、または実行中の場合はcommand
何とか自分の元のディレクトリに戻るにはその能力に影響を与えます- $OLDPWD
。その場合、cd -
最後の処理も行い、結果の現在の作業ディレクトリ名をstderrに書き込みます。
youtube-dl
。