Você está muito perto. Você pode fazer o que quiser com
while read line; do pushd "$line"; done < <(find "$(pwd)" -type d)
O problema com o seu comando é que pushd
, como cd
,
deve ser feito no processo principal (pai) para ser útil,
e (com alguma variação baseada em como seu sistema está configurado),
os comandos em um pipeline são executados em subprocessos (processos filho).
< <(cmd)
magicamente te dá um cachimbo
sem lhe dar um pipeline.
Isso requer que você esteja executando o bash
(ou talvez um dos outros shells avançados?),
já que o POSIX não suporta <(cmd)
.
A abordagem xargs
, infelizmente, estava fadada ao fracasso
porque pushd
(como cd
) é um comando interno do shell
(isto é, não existe nenhum programa chamado pushd
),
e xargs
requer um programa externo e executável.
Você pode obter uma saída que (quase) parece correta com este comando:
$ find "$(pwd)" -type d | xargs -i sh -c 'pushd "$1"' sh
~/foo ~/foo
~/foo/bar1 ~/foo
~/foo/bar2 ~/foo
~/foo/bar3 ~/foo
mas que está executando o shell como um programa externo, e fazendo isso (independentemente) para cada diretório. Isso é um pouco mais perto:
$ 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
executando um único processo de shell,
e dizendo para fazer um loop em todos os diretórios.
Como você pode ver,
esta técnica é semelhante à sua segunda tentativa (e minha resposta),
e o resultado é o mesmo da sua segunda tentativa -
você recebe um novo processo de shell que chama pushd
quatro vezes,
e acaba com uma pilha de diretórios com cinco níveis de profundidade
(contando o diretório inicial duas vezes) -
mas esse novo processo de shell está em um subprocesso,
e, quando você vir o próximo prompt do shell, esse processo do shell desapareceu.
Para referência, note que este comando é um pouco semelhante ao
uma resposta que dei há alguns anos .
Stéphane Chazelas discute
a construção do comando sh -c long_complex_shell_command sh
aqui e aqui .