Using the exec() family to run the "cd" command

19,338

Solution 1

exec loads an executable file and replaces the current program image with it. As you rightly noted, cd is not an executable file, but rather a shell builtin. So the executable that you want to run is the shell itself. This is of course what system() does for you, but if you want to be explicit about it, you can use exec:

execl("/bin/sh", "-c", "cd", (const char *)0);

Since this replaces your current process image, you should do this after fork()ing off a new process.

However, this entire procedure has absolutely no effect. If you want to change the directory in your current process, use chdir().

Solution 2

You're better off using int chdir(const char *path); found in unistd.h.

Solution 3

No it is not, and it would be of no use. chdir (the function that changes a process's current directory) only affects the process that calls it (and its children). It does not affect its parent in particular.

So execing cd has no point, since the process would exit immediately after having changed directories.

(You could exec something like bash -c cd /tmp if you really want to, but as I said, this is fruitless.)

Solution 4

While, as already stated system("cd xxx") wouldn't change your application current directory, it is not completely useless.

You can still use system exit status to know if changing your current directory to the one stated would succeed or not.

Similarly, if you like complex solutions, you could also do the same with fork/exec, either with exec'ing /bin/sh -c cd xxx or simply /bin/cd xxx with OSes that provide an independent cd executable.

I would however recommend this non overkill faster equivalent access("xxx", X_OK|R_OK)

Note: All POSIX compliant OSes must provide an independent cd executable. This is at least the case with Solaris, AIX, HP-UX and Mac OS/X.

Share:
19,338
goofy
Author by

goofy

Updated on June 27, 2022

Comments

  • goofy
    goofy almost 2 years

    I know that cd is a shell built-in ,and I can run it by using system().

    But is that possible to run the cd command by the exec() family, like execvp()?

    Edit: And I just noticed that system("cd") is also meaningless。Thanks for the help of everyone.

  • glglgl
    glglgl about 12 years
    A independent cd executable is just and plain impossible.
  • jlliagre
    jlliagre about 12 years
    There is definitely one on the OS I'm using.
  • adl
    adl about 12 years
    @jliagre: Backup the last paragraph with pointers. E.g. link to the end of pubs.opengroup.org/onlinepubs/9699919799/utilities/… where it is said that all of the standard utilities, including the regular built-ins [...], shall be implemented in a manner so that they can be accessed via the exec family of functions. And to Solaris's cd man docs.oracle.com/cd/E19253-01/816-5165/6mbb0m9bl/index.html that states /usr/bin/cd has no effect on the invoking process but can be used to determine whether or not a given directory can be set as the current directory
  • User
    User about 9 years
    Can you walk through what the argument represent?
  • Kerrek SB
    Kerrek SB about 9 years
    @User: The arguments make up the command that's being executed, and since this is a variable-argument function, we have to signal the end of the arguments somehow, which in this case is done by a null pointer of type const char *. So the command that's executed is: /bin/sh -c cd