LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 03-18-2010, 02:29 AM   #1
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Rep: Reputation: 19
xargs cd is not working


Please explain why
Code:
echo some_directory | xargs cd
is not working.
Code:
echo some_directory | xargs ls
is working as expected.
 
Old 03-18-2010, 06:15 AM   #2
HasC
Member
 
Registered: Oct 2009
Location: South America - Paraguay
Distribution: Debian 5 - Slackware 13.1 - Arch - Some others linuxes/*BSDs through KVM and Xen
Posts: 329

Rep: Reputation: 55
What means 'not working'
What error message gives to you?
 
Old 03-18-2010, 06:41 AM   #3
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by doru View Post
Please explain why
Code:
echo some_directory | xargs cd
is not working.
Code:
echo some_directory | xargs ls
is working as expected.
If I presume correctly ...

It is working but it is not meeting your expectations. You expect that, after the cd pipe, your current directory will be the new directory. It doesn't work because only the first command in a pipleine is run in the current shell; the xargs runs in a subshell; in the subshell, cd does work (but you can't see it). When the pipeline has finished the current directory is unchanged because it never was changed in the current shell.
 
Old 03-20-2010, 03:10 AM   #4
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Thanks for your answers!

HasC: This is what I get:

Quote:
$ echo test | xargs cd
xargs: cd: No such file or directory
catkin: I would be happy to know that your explanation is right, but then, why do I get the above mentioned error message?

Last edited by doru; 03-20-2010 at 03:11 AM. Reason: put bold
 
Old 03-21-2010, 02:55 AM   #5
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by doru View Post
... why do I get the above mentioned error message?
Because xargs is searching the directories listed in $PATH for a file called cd and there isn't one because cd is (must be) a shell builtin
Code:
[c@CW8:~$ type cd
cd is a shell builtin
Do you know why cd must be a builtin? If you don't, can you figure it out?

Last edited by catkin; 03-21-2010 at 02:57 AM. Reason: [CODE] tags error
 
1 members found this post helpful.
Old 03-21-2010, 06:30 AM   #6
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Thanks, indeed, cd is builtin and ls is not.

Quote:
Do you know why cd must be a builtin? If you don't, can you figure it out?
Maybe because cd has to change an environment variable in the current shell, and non-builtins run in subshells?

Could you please explain to me why does echo builtin have a file in /bin, while cd does not? So the relevant difference between cd and ls is not that one is builtin and the other one is not, but that cd has to change an environment variable in the current shell, and the other doesn't? And xargs is simply protecting me from a meaningless command, by refusing to run it if it does not have a file in /bin? All this would be amazing! Thanks for your answer, please verify my guess.
 
Old 03-21-2010, 07:01 AM   #7
MTK358
LQ 5k Club
 
Registered: Sep 2009
Posts: 6,443
Blog Entries: 3

Rep: Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723Reputation: 723
It does seem to have both here! I wonder why.

Code:
$ type echo
echo is a shell builtin
$ which echo
/bin/echo
$ echo "Test"
Test
$ /bin/echo "Test"
Test
I don't know if this could be true, but maybe it's for other shells that don't have an echo command built-in?

Last edited by MTK358; 03-21-2010 at 07:05 AM.
 
Old 03-21-2010, 07:19 AM   #8
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by MTK358 View Post
I don't know if this could be true, but maybe it's for other shells that don't have an echo command built-in?
This is possible,
Quote:
$ type /bin/echo
/bin/echo is /bin/echo
but xargs is using echo by default, if no command is specified, so it has to be a /bin/echo, if there is xargs.
 
Old 03-21-2010, 07:43 AM   #9
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by doru View Post
Thanks, indeed, cd is builtin and ls is not.

Maybe because cd has to change an environment variable in the current shell, and non-builtins run in subshells?
cd does change a variable in the current shell but that is not the most significant factor. Non-builtins ("external commands" in shell-speak) do run in child processes and that is key to why cd must be a builtin. Try these commands (the first runs cd in a subshell)
Code:
(cd /tmp; pwd)
pwd
Quote:
Originally Posted by doru View Post
Could you please explain to me why does echo builtin have a file in /bin, while cd does not?
Historically echo was an external command but it was very commonly used in shellscripts which meant creating a sub-process each time which used a lot of system resources so it was made a builtin for efficiency and performance. The external /usr/bin/echo was still required for the likes of xargs, as you mentioned, because xargs is a binary running in a sub-process so does not have access to the shell builtin echo.
Quote:
Originally Posted by doru View Post
And xargs is simply protecting me from a meaningless command, by refusing to run it if it does not have a file in /bin?
More simply, xargs can't find the cd command; the most helpful thing it can do is to report that.
 
Old 03-22-2010, 04:29 AM   #10
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by catkin View Post
The external /usr/bin/echo was still required for the likes of xargs, as you mentioned, because xargs is a binary running in a sub-process so does not have access to the shell builtin echo.

More simply, xargs can't find the cd command; the most helpful thing it can do is to report that.
Thank you for your explanation. Could you please clarify why is cd not available in the subprocess. The holy bash manual says:
Quote:
Each command in a pipeline is executed as a separate process (i.e., in a subshell).
Quote:
(list) list is executed in a subshell environment. [...] Variable assignments and builtin commands that affect the shell’s environment do not remain in effect after the command completes.
Quote:
Builtin commands that are invoked as part of a pipeline are also executed in a subshell environment.
The subshell inherits the environment, so it is more than a simple sub-process, it is a shell. Therefore, shell builtins should have been available there, too. (Is it possible to have a process which runs outside any shell?)
 
Old 03-22-2010, 05:21 AM   #11
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by doru View Post
Thank you for your explanation. Could you please clarify why is cd not available in the subprocess. The holy bash manual says: The subshell inherits the environment, so it is more than a simple sub-process, it is a shell. Therefore, shell builtins should have been available there, too. (Is it possible to have a process which runs outside any shell?)
To answer you last question first: yes, it is not only possible but common to have a process which is executing a program which is not a shell. That is the only way a program that is not a script can run. Shells run non-scripts in child processes, not sub-shells.

A shell is a process in which one of the shell binary executables (usually listed in /etc/shells) is running. When bash runs a pipleline, say echo foo | xargs, the first command in the pipleine (echo foo) runs in the current shell and bash starts a child process to run xargs. Bash does not execute a shell in the child process but the /usr/bin/xargs binary executable. Thus there is no shell running in the xargs child process so xargs does not have shell features available including shell builtins.

To understand this you need to know about processes, programs (especially the difference between a process and a program) and shells. Wikipedia may be helpful.
 
Old 03-22-2010, 06:58 AM   #12
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by catkin View Post
To answer you last question first: yes, it is not only possible but common to have a process which is executing a program which is not a shell. That is the only way a program that is not a script can run. Shells run non-scripts in child processes, not sub-shells.

A shell is a process in which one of the shell binary executables (usually listed in /etc/shells) is running. When bash runs a pipleline, say echo foo | xargs, the first command in the pipleine (echo foo) runs in the current shell and bash starts a child process to run xargs. Bash does not execute a shell in the child process but the /usr/bin/xargs binary executable. Thus there is no shell running in the xargs child process so xargs does not have shell features available including shell builtins.

To understand this you need to know about processes, programs (especially the difference between a process and a program) and shells. Wikipedia may be helpful.
I read an introductory book on Unix, so I know some about processes and programs. Only the practical application of these notions seems a bit cumbersome.

It seems that xargs simply refuses to start yet another subshell to run the command it receives as an argument in it, and expects external commands only. This explanation fits both the Unix and the bash manuals.
Code:
echo test | xargs cd
bash creates subshells for echo test and for xargs cd, but xargs refuses to create another subshell for cd. That is all. PS: bash is external.

Thanks for your help.

Last edited by doru; 03-22-2010 at 07:06 AM. Reason: thanks
 
Old 03-23-2010, 05:05 AM   #13
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by catkin View Post
A shell is a process in which one of the shell binary executables (usually listed in /etc/shells) is running.

Shells run non-scripts in child processes, not sub-shells.

When bash runs a pipeline, say echo foo | xargs, the first command in the pipeline (echo foo) runs in the current shell and bash starts a child process to run xargs.
The first two statements are correct, the third one is false, but all three are very important.

You can see that the third statement is incorrect by running:

Code:
dave@router2:~$ ls -dl tmp tst
drwxr-xr-x 2 dave dave 4096 2010-02-25 12:46 tmp
drwxr-xr-x 2 dave dave 4096 2010-03-22 18:33 tst
dave@router2:~$ cd tmp | cd tst
dave@router2:~$ pwd
/home/dave
See?
 
Old 03-23-2010, 05:32 AM   #14
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
Quote:
Originally Posted by doru View Post
The first two statements are correct, the third one is false
Thanks for the correction and the demo doru

The GNU Bash Reference says: "Each command in a pipeline is executed in its own subshell ..."
 
Old 03-23-2010, 12:42 PM   #15
doru
Member
 
Registered: Sep 2008
Distribution: Ubuntu 8.04 LTS Server
Posts: 138

Original Poster
Rep: Reputation: 19
Quote:
Originally Posted by catkin View Post
Thanks for the correction and the demo doru
I am glad that I have contributed a little bit.
 
  


Reply

Tags
cd, xargs



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] xargs and cp --parents amchargue Linux - Newbie 7 10-09-2009 12:12 PM
Using xargs SBN Linux - General 2 04-07-2008 07:44 PM
Xargs -i problems. Glaurung Linux - Software 2 10-25-2007 03:23 AM
`wc`, `xargs` h/w Programming 11 09-30-2007 04:22 PM
xargs yawe_frek Linux - Software 1 04-15-2007 04:26 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 12:15 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration