Sponsored Content
Full Discussion: Cd
Top Forums UNIX for Dummies Questions & Answers Cd Post 7908 by Perderabo on Wednesday 3rd of October 2001 09:50:54 AM
Old 10-03-2001
Folks, the current working directory is a datum that is stored on a per-process basis. The chdir(2) changes this value for the current process. After a fork(2), the child process will inherit the cwd from its parent.

Now think about the code:
cd /etc
cat passwd

This is being executed by a shell. Let's say the shell has a pid of 1200. When the shell encounters the "cd /etc" line, we really must have the cd command executed by the current shell as a built-in. So then shell the will execute the c code "chdir(/etc)" which sets the shell's cwd to /etc. Next, the shell encounters the "cat passwd" command. This is not a built-in. So the shell must fork(2). The parent shell, pid 1200, will simply wait(2) for the child. But the child process, let's say it got pid 2200, will exec(2) the cat program. When cat(1) starts to run, it still has "/etc" as its cwd. So when it opens the file called passwd, it will actually be opening "/etc/passwd". Eventually, pid 2200, will exit. This will cause pid 1200 to finally return from its wait call. Pid 1200 can get pid 2200's exit code from the wait call. But that's the only thing it will get from pid 2200.

Now think about:
/usr/bin/cd /etc
cat passwd

Here we have a problem. /usr/bin/cd is not a built-in. So the shell forks creating process pid 2200. 2200 will then exec(2) /usr/bin/cd. Now process 2200, which is now cd will invoke chdir("/etc") and so now it's cwd is indeed /etc. But now it exits. The shell, still pid 1000, returns from its wait call. But we have not changed the shell's current working directory. So now the shell encounters "cat passwd". It forks, creating pid, say. 2201. Process 2201 will then exec the cat command. But the cat command has inherited the cwd from the shell. It has no way to know that previously the shell executed "/usr/bin/cd /etc". We are in the wrong directory. This is why cd must be a shell built-in. cd was built-in even in the first bourne shell.

From a shell, any shell, try:
cd /
cat passwd
/usr/bin/cd /etc
cat passwd
pwd
cd /etc
cat passwd
pwd

It is only recently that /usr/bin/cd has started to exist. Unix got along fine without it for decades and it would get along fine if it vanished. It is largely useless and very misleading as this thread has shown. The only semi-rational reason to ever code something like:
/usr/bin/cd /etc
would be if you wanted to test whether or not you can sucessfully "cd /etc". The exit code from /usr/bin/cd indicates whether or not the chdir succeeded. You could check the exit code. But I have a suspicion that /usr/bin/cd may be someone's idea of a joke.
 
wait(1) 						      General Commands Manual							   wait(1)

NAME
wait - await process completion SYNOPSIS
[pid] DESCRIPTION
If no argument is specified, waits until all processes (started with of the current shell have completed, and reports on abnormal termina- tions. If a numeric argument pid is given and is the process ID of a background process, waits until that process has completed. Other- wise, if pid is not a background process, exits without waiting for any processes to complete. Because the system call must be executed in the parent process, the shell itself executes without creating a new process (see wait(2)). Command-Line Arguments supports the following command line arguments: The unsigned decimal integer process ID of a command, whose termination is to wait for. WARNINGS
Some processes in a 2-or-more-stage pipeline may not be children of the shell, and thus cannot be waited for. SEE ALSO
csh(1), ksh(1), sh-posix(1), sh(1), wait(2). STANDARDS CONFORMANCE
wait(1)
All times are GMT -4. The time now is 09:40 AM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy