46

Feeling like an idiot right now. Why does this not work?

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

2 Answers 2

39

The pipe runs xargs in a subprocess, and xargs runs cd in a subprocess. Changes in a subprocess do not get propagated to the parent process.

6
  • That makes complete sense. Thanks for helping a Unix noob. Nov 3, 2010 at 19:36
  • 4
    You can get the effect you want by using back-quotes: cd `echo "/some/directory/path" | cut -d\ -f1` (Note that I added 'cut' to split on spaces and grab the first item the way xargs does) Nov 3, 2010 at 20:27
  • 8
    Actually, xargs can't run cd since it's, of necessity, a shell builtin and xargs can only run free-standing executables. What you said is true about subprocesses, however. Nov 3, 2010 at 20:36
  • /usr/bin/cd is definitely a Unix free standing documented command, at least on Solaris.
    – jlliagre
    Nov 3, 2010 at 23:31
  • Using @Slartibartfast for auto-generated paths: cd `port file libcudd | sed -e 's/\/Portfile//'` (usually long ones you don't want to handle manually, like this MacPorts Portfile location).
    – 0 _
    Dec 5, 2013 at 10:22
33

The command cd is a built-in because the information about the current directory is tied to a process and only shell built-in can change current directory of the running shell.

There are two problems with your code:

  1. xargs cannot run cd because cd is a built-in command and xargs can run only executable files.
  2. Even if you run cd in a sub-process called from xargs, it will not have any effect on the parent process as explained above.

The solution is to run a sub-shell, inside it run cd and then you can execute commands in the new current directory.

ls | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
3
  • It doesn't make sense to do ls | xargs ... in this example. It should be passing in the value for $0, like echo "/some/directory/path" | xargs -L 1 bash -c 'cd "$0" && pwd && ls'
    – wisbucky
    Nov 6, 2018 at 23:36
  • 1
    IMO a better solution would be : ls | xargs -L 1 -I @@ bash -c 'cd @@ && pwd && ls'
    – Roman M
    Jun 16, 2019 at 14:43
  • This should be the accepted answer Mar 4, 2022 at 6:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .