usando xargs para cd em um diretório

28

Sentindo-me como um idiota agora. Por que isso não funciona?

echo "/some/directory/path" | xargs -n1 cd
Ian Lotinsky
fonte

Respostas:

22

O canal executa xargs em um subprocesso e xargs executa cd em um subprocesso. Alterações em um subprocesso não são propagadas para o processo pai.

Ignacio Vazquez-Abrams
fonte
Isso faz total sentido. Obrigado por ajudar um noob Unix.
11266 Ian Ianinsinsky
3
Você pode obter o efeito desejado usando back-citações: cd `echo "/some/directory/path" | cut -d\ -f1` (Note que eu adicionei 'cut' para dividir em espaços e pegue o primeiro item a forma como xargs faz)
Slartibartfast
5
Na verdade, xargsnão pode ser executado, cdpois é, necessariamente, um shell embutido e xargssó pode executar executáveis ​​independentes. O que você disse é verdade sobre subprocessos, no entanto.
Pausado até novo aviso.
/ usr / bin / cd é definitivamente um comando documentado independente do Unix, pelo menos no Solaris.
Jlliagre
Usando @Slartibartfast para caminhos gerados automaticamente: cd `port file libcudd | sed -e 's/\/Portfile//'` (geralmente os longos que você não deseja manipular manualmente, como este local do MacPorts Portfile).
Ioannis Filippidis
23

O comando cdé interno porque as informações sobre o diretório atual estão vinculadas a um processo e apenas o shell interno pode alterar o diretório atual do shell em execução.

Há dois problemas com seu código:

  1. xargsnão pode ser executado cdporque cdé um comando interno e xargspode executar apenas arquivos executáveis.
  2. Mesmo se você executar cdem um subprocesso chamado from xargs, ele não terá nenhum efeito no processo pai, conforme explicado acima.

A solução é executar um sub-shell, dentro dele, executar cde, em seguida, você pode executar comandos no novo diretório atual.

ls | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
parpa
fonte
Não faz sentido fazer ls | xargs ...neste exemplo. Deveria estar passando o valor para $0, como #echo "/some/directory/path" | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
wisbucky 6/11/18
Na IMO, uma solução melhor seria: sl | xargs -L 1 -I @@ o bash -c 'cd @@ && pwd && ls'
Roman M