Linux - NewbieThis 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
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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.
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
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
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.
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?)
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.
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
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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.