usando xargs para cd a un directorio

28

Sintiéndose como un idiota en este momento. ¿Por qué esto no funciona?

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

Respuestas:

22

La tubería ejecuta xargs en un subproceso y xargs ejecuta cd en un subproceso. Los cambios en un subproceso no se propagan al proceso padre.

Ignacio Vazquez-Abrams
fuente
Eso tiene mucho sentido. Gracias por ayudar a un novato de Unix.
Ian Lotinsky, el
3
Puede obtener el efecto que desee utilizando comillas inversas: cd `echo "/some/directory/path" | cut -d\ -f1` (Tenga en cuenta que agregué 'cortar' para dividir en espacios y tomar el primer elemento de la manera que lo hace xargs)
Slartibartfast
55
En realidad, xargsno puede ejecutarse cdya que es, necesariamente, un shell integrado y xargssolo puede ejecutar ejecutables independientes. Sin embargo, lo que dijo es cierto sobre los subprocesos.
Pausado hasta nuevo aviso.
/ usr / bin / cd es definitivamente un comando documentado independiente de Unix, al menos en Solaris.
jlliagre el
Uso de @Slartibartfast para rutas generadas automáticamente: cd `port file libcudd | sed -e 's/\/Portfile//'` (generalmente las largas que no desea manejar manualmente, como esta ubicación de MacPorts Portfile).
Ioannis Filippidis
23

El comando cdestá integrado porque la información sobre el directorio actual está vinculada a un proceso y solo el shell integrado puede cambiar el directorio actual del shell en ejecución.

Hay dos problemas con su código:

  1. xargsno se puede ejecutar cdporque cdes un comando incorporado y xargssolo puede ejecutar archivos ejecutables.
  2. Incluso si ejecuta cdun subproceso llamado desde xargs, no tendrá ningún efecto en el proceso principal como se explicó anteriormente.

La solución es ejecutar un sub-shell, dentro de él ejecutar cdy luego puede ejecutar comandos en el nuevo directorio actual.

ls | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
parpadea
fuente
No tiene sentido hacerlo ls | xargs ...en este ejemplo. Debería pasar el valor para $0, comoecho "/some/directory/path" | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
wisbucky
OMI, una mejor solución sería: ls | xargs -L 1 -I @@ bash -c 'cd @@ && pwd && ls'
Roman M