Running a shell command in a c program

13,807

Solution 1

fork() and system() is what you need

Solution 2

Sure, just fork and exec: use fork to create a new process and, in the child process, use exec to start the shell with your command. execv takes the arguments you would normally give to the shell.

Your code could look like this:

pid_t child_pid = fork();
if (child_pid == 0)
{   // in child
    /* set up arguments */
    // launch here
    execv("/bin/sh", args);
    // if you ever get here, there's been an error - handle it
}
else if (child_pid < 0)
{   // handle error
}

the child process will send a SIGCHLD signal when it dies. This code quoted from the POSIX standard (SUSv4) will handle that:

static void
handle_sigchld(int signum, siginfo_t *sinfo, void *unused)
{
    int status;

    /*
     * Obtain status information for the child which
     * caused the SIGCHLD signal and write its exit code
     * to stdout.
    */
    if (sinfo->si_code != CLD_EXITED)
    {
        static char msg[] = "wrong si_code\n";
        write(2, msg, sizeof msg - 1);
    }
    else if (waitpid(sinfo->si_pid, &status, 0) == -1)
    {
        static char msg[] = "waitpid() failed\n";
        write(2, msg, sizeof msg - 1);
    }
    else if (!WIFEXITED(status))
    {
        static char msg[] = "WIFEXITED was false\n";
        write(2, msg, sizeof msg - 1);
    }
    else
    {
        int code = WEXITSTATUS(status);
        char buf[2];
        buf[0] = '0' + code;
        buf[1] = '\n';
        write(1, buf, 2);
    }
}

Solution 3

What about simply amping the command with system ("command &")?

Solution 4

Try code like this:

#include <stdlib.h>
#include <unistd.h>
int main(int argc, char ** argv)
{
     if (!fork())
     {
         execv("ls", {"myDir"}); /* Your command with arguments instead of ls. */
     }
}
Share:
13,807

Related videos on Youtube

wonnie
Author by

wonnie

Updated on June 04, 2022

Comments

  • wonnie
    wonnie almost 2 years

    I want to run a shell command in my c program. But the thing is that i don't want to make my program wait until the command performed. No need to read the shell command's output (it returns no data anyway) So basically, is that possible?

    • Jens
      Jens about 13 years
      BTW, it does not matter if you want to run a shell command or some other executable. Whether you use system() or the fork()/exec() approach, all that's required is an executable. Maybe you want to edit the title of your question accordingly?
  • PhD
    PhD about 13 years
    Along with exec() or its variants, probably.
  • rlc
    rlc about 13 years
    system would have the child process wait for the shell command - exec would replace the child process with the shell..
  • Stefano Borini
    Stefano Borini about 13 years
    @Ronald: no. It replaces the child process with another process. It's not clear from the OP if he wants to run another program or a shell command line, but if it's the latter, then only system() will do the trick. exec does not involve the shell.
  • Stefano Borini
    Stefano Borini about 13 years
    exec does not involve the shell. suppose the OP wants to run ls | grep -v hello. This will work with system, but will not work with exec.
  • rlc
    rlc about 13 years
    it will if you pass it the proper arguments (i.e. start /bin/sh and pass it the script you want to run).
  • rlc
    rlc about 13 years
    the OP can pass those to the shell - system does the same thing (but does another fork & exec behind the scenes).
  • Jens
    Jens about 13 years
    This strikes me as too quick and dirty as this would create a zombie process from the time the command exits until main exits. A well-behaved Unix program would want to avoid that. See other answers that use waitpid.

Related