foo
私はサブディレクトリを含むディレクトリにあり、bar1
bar2
それがbar3
すべてです。
pushd
、およびをfoo
1つのコマンドで実行したいのですが、停止しました。bar1
bar2
bar3
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
何が間違っているのかを理解できる人はいますか?
答え1
あなたは非常に近いです。欲しいことができます
while read line; do pushd "$line"; done < <(find "$(pwd)" -type d)
コマンドの問題は、有用な場合は基本(親)プロセスでpushd
実行するcd
必要があり(システムの設定方法によって若干の違いがある)、パイプラインのコマンドが子プロセス(子プロセス)で実行されることです。 )。パイプを与えずに魔法のようにパイプを与えます。< <(cmd)
POSIXは 。<(cmd)
残念ながら、このxargs
アプローチは失敗する運命です。なぜならpushd
(like cd
)はシェル組み込み(つまり、プログラム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回呼び出される新しいシェルプロセスが取得され、最終的にAディレクトリスタックが作成されます。つまり、5つのレベルの深さ(開始ディレクトリを2回計算) - しかし、新しいシェルプロセスは子プロセスにあり、次のシェルプロンプトが表示された場合それシェルプロセスが消えた。
ちなみに、コマンドは次のように似ています。
私が数年前にした答えは。
スティーブン・チャジェラスコマンド構造の議論
sh -c long_complex_shell_command sh
ここそしてここ。
答え2
これは仕事ではありませんfind
。
for subdirectory in */; do
pushd -- "$subdirectory"
done
pushd
たとえば、cd
影響を与えるシェル環境でコードを実行する必要があるため、コードは機能しません。pushd
外部コマンドには意味がないため、呼び出すことができるxargs
外部コマンドはありません。何の影響もありません。パイプの右側はサブシェルで実行されます(シェルの内側には他のシェルで実行されているいくつかのシェルがあり、2番目の試みが機能していることがわかります)pushd
。
find `pwd` | {
while read line ; do pushd $line ; done;
dirs
}
ディレクトリ名に特殊文字が含まれていない場合は有効です。変数置換を削除する理由がわからない限り、必ず変数置換の周りに二重引用符を入れてください。。