utiliser xargs pour cd dans un répertoire

28

Se sentir comme un idiot en ce moment. Pourquoi ça ne marche pas?

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

Réponses:

22

Le canal exécute xargs dans un sous-processus et xargs exécute cd dans un sous-processus. Les modifications dans un sous-processus ne sont pas propagées au processus parent.

Ignacio Vazquez-Abrams
la source
Cela est parfaitement logique. Merci d'avoir aidé un noob Unix.
Ian Lotinsky
3
Vous pouvez obtenir l'effet que vous souhaitez en utilisant des guillemets: cd `echo "/some/directory/path" | cut -d\ -f1` (Notez que j'ai ajouté «couper» pour diviser les espaces et récupérer le premier élément comme le fait xargs)
Slartibartfast
5
En fait, xargsne peut pas fonctionner cdcar il s'agit nécessairement d'un shell intégré et xargsne peut exécuter que des exécutables autonomes. Cependant, ce que vous avez dit est vrai au sujet des sous-processus.
pause jusqu'à nouvel ordre.
/ usr / bin / cd est définitivement une commande documentée autonome Unix, au moins sur Solaris.
jlliagre
Utilisation de @Slartibartfast pour les chemins générés automatiquement: cd `port file libcudd | sed -e 's/\/Portfile//'` (généralement les longs que vous ne voulez pas gérer manuellement, comme cet emplacement de port MacPorts).
Ioannis Filippidis
23

La commande cdest intégrée car les informations sur le répertoire en cours sont liées à un processus et seul le shell intégré peut changer le répertoire en cours du shell en cours d'exécution.

Il y a deux problèmes avec votre code:

  1. xargsne peut pas s'exécuter cdcar cdest une commande intégrée et xargsne peut exécuter que des fichiers exécutables.
  2. Même si vous exécutez cddans un sous-processus appelé depuis xargs, cela n'aura aucun effet sur le processus parent comme expliqué ci-dessus.

La solution consiste à exécuter un sous-shell, à l'intérieur de celui-ci s'exécuter cdet ensuite vous pouvez exécuter des commandes dans le nouveau répertoire courant.

ls | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
parpa
la source
Cela n'a pas de sens de le faire ls | xargs ...dans cet exemple. Il devrait passer la valeur pour $0, commeecho "/some/directory/path" | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
wisbucky
OMI, une meilleure solution serait: ls | xargs -L 1 -I @@ bash -c 'cd @@ && pwd && ls'
Roman M