私は、サブディレクトリbar1
bar2
とbar3
を含むディレクトリfoo
にいます。
1つのコマンドでpushd
、bar1
、bar2
、およびbar3
に対してfoo
を実行したいのですが、問題が発生しています。
find `pwd` | xargs pushd
戻り値
xargs: pushd: No such file or directory
Whileループで問題を回避しようとしました:
find `pwd` | while read line ; do pushd $line ; done
これは正しいように見える出力を与えます:
~/foo ~/foo
~/foo/bar1 ~/foo ~/foo
~/foo/bar2 ~/foo/bar1 ~/foo ~/foo
~/foo/bar3 ~/foo/bar2 ~/foo/bar1 ~/foo ~/foo
ただし、その後dirs
を使用すると、スタックに新しいディレクトリを追加していないことがわかります。
~/foo
誰かが私が間違っていることを見つけることができますか?
あなたはとても近くにいます。あなたはあなたがやりたいことをすることができます
_while read line; do pushd "$line"; done < <(find "$(pwd)" -type d)
_
コマンドの問題は、pushd
と同様に、cd
を使用するには、メイン(親)プロセスで実行する必要があることです(システムの設定方法によって多少異なります)。 、パイプライン内のコマンドはサブプロセス(子プロセス)で実行されます。 < <(cmd)
は、パイプラインを提供せずに魔法のようにパイプを提供します。
POSIXは<(cmd)
をサポートしていないため、これにはbash(または他の高度なシェルの1つ?)を実行している必要があります。
残念ながら、xargs
(pushd
など)はシェルの組み込みコマンドであるため、cd
アプローチは失敗する運命にありました(つまり、programはpushd
)と呼ばれ、xargs
には外部の実行可能プログラムが必要です。このコマンドを使用すると、(ほぼ)正しく見える出力を取得できます。
_$ find "$(pwd)" -type d | xargs -i sh -c 'pushd "$1"' sh
~/foo ~/foo
~/foo/bar1 ~/foo
~/foo/bar2 ~/foo
~/foo/bar3 ~/foo
_
ただし、これはシェルを外部プログラムとして実行し、ディレクトリごとに(独立して)実行します。これは少し近いです:
_$ find "$(pwd)" -type d | xargs sh -c 'for line do pushd "$line"; done' sh
~/foo ~/foo
~/foo/bar1 ~/foo ~/foo
~/foo/bar2 ~/foo/bar1 ~/foo ~/foo
~/foo/bar3 ~/foo/bar2 ~/foo/bar1 ~/foo ~/foo
_
単一のシェルプロセスを実行し、すべてのディレクトリをループするように指示します。ご覧のとおり、この手法は2回目の試行(および私の答え)と同様であり、結果は2回目の試行と同じです。pushd
を4回呼び出す新しいシェルプロセスを取得し、最終的には5レベルの深さのディレクトリスタック(開始ディレクトリを2回カウント)を使用しますが、その新しいシェルプロセスはサブプロセス内にあり、次のシェルプロンプトが表示されるまでに、thatシェルプロセスがなくなりました。
参考までに、このコマンドは 数年前に私が出した答え にいくぶん似ていることに注意してください。 StéphaneChazelas _sh -c long_complex_Shell_command sh
_コマンド構造について説明します ここ および ここ 。
これはfind
の仕事ではありません。
for subdirectory in */; do
pushd -- "$subdirectory"
done
pushd
と同様にcd
は、影響を与えるシェル環境で実行する必要があるため、コードは機能しません。外部コマンドは無意味であるため、pushd
が呼び出すことができる外部コマンドxargs
はありません。何にも影響しません。パイプの右側はサブシェルで実行されます(シェルには、他のシェルで実行されるシェルがあり、2回目の試行で機能します)。 pushd
が
find `pwd` | {
while read line ; do pushd $line ; done;
dirs
}
ディレクトリ名に特殊文字が含まれていない限り、つまり機能します。 変数の置換を省略する必要がある理由がわからない限り、変数の置換は常に二重引用符で囲みます 。