usando xargs per cd in una directory


26

Sentirsi come un idiota in questo momento. Perché questo non funziona?

echo "/some/directory/path" | xargs -n1 cd

Risposte:


20

La pipe esegue xargs in un sottoprocesso e xargs esegue cd in un sottoprocesso. Le modifiche in un sottoprocesso non vengono propagate al processo padre.


Questo ha perfettamente senso. Grazie per l'aiuto a un noob Unix.
Ian Lotinsky,

2
Puoi ottenere l'effetto desiderato usando le virgolette: cd `echo "/some/directory/path" | cut -d\ -f1` (Nota che ho aggiunto 'taglia' per dividere gli spazi e afferrare il primo oggetto come fa xargs)
Slartibartfast,

5
In realtà, xargsnon può essere eseguito cdpoiché, per necessità, è incorporato nella shell e xargspuò eseguire solo eseguibili indipendenti. Ciò che hai detto è vero sui sottoprocessi, tuttavia.
Dennis Williamson,

/ usr / bin / cd è sicuramente un comando documentato indipendente di Unix, almeno su Solaris.
jlliagre,

Usare @Slartibartfast per percorsi generati automaticamente: cd `port file libcudd | sed -e 's/\/Portfile//'` (di solito quelli lunghi che non vuoi gestire manualmente, come questa posizione del Portfile di MacPorts).
Ioannis Filippidis,

23

Il comando cdè incorporato perché le informazioni sulla directory corrente sono legate a un processo e solo la shell incorporata può cambiare la directory corrente della shell in esecuzione.

Esistono due problemi con il codice:

  1. xargsimpossibile eseguire cdperché cdè un comando incorporato e xargspuò eseguire solo file eseguibili.
  2. Anche se si esegue cdun processo secondario chiamato da xargs, non avrà alcun effetto sul processo padre come spiegato sopra.

La soluzione è eseguire una sotto-shell, al suo interno eseguire cde quindi è possibile eseguire i comandi nella nuova directory corrente.

ls | xargs -L 1 bash -c 'cd "$0" && pwd && ls'

Non ha senso fare ls | xargs ...in questo esempio. Dovrebbe passare il valore per $0, tipoecho "/some/directory/path" | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
wisbucky

IMO una soluzione migliore sarebbe: ls | xargs -L 1 -I @@ bash -c 'cd @@ && pwd && ls'
Roman M
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.