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
ここそしてここ。