【问题标题】:Running a shell command in a c program在 c 程序中运行 shell 命令
【发布时间】:2011-08-02 07:38:05
【问题描述】:

我想在我的 c 程序中运行一个 shell 命令。但问题是我不想让我的程序等到命令执行。无需读取 shell 命令的输出(反正它不返回任何数据)所以基本上,这可能吗?

【问题讨论】:

  • 顺便说一句,如果你想运行 shell 命令或其他可执行文件并不重要。无论您使用system() 还是fork()/exec() 方法,只需要一个可执行文件即可。也许您想相应地编辑问题的标题?

标签: c linux shell


【解决方案1】:

fork()system() 是您所需要的

【讨论】:

  • 可能还有 exec() 或其变体。
  • system 会让子进程等待 shell 命令 - exec 会用 shell 替换子进程。
  • @Ronald:没有。它用另一个进程替换子进程。 OP 不清楚他是否想运行另一个程序或 shell 命令行,但如果是后者,那么只有 system() 可以解决问题。 exec 不涉及shell。
  • 如果你传递正确的参数(即启动 /bin/sh 并传递你想要运行的脚本),它会。
【解决方案2】:

当然,只需forkexec:使用fork 创建一个新进程,并在子进程中使用exec 使用您的命令启动shell。 execv 接受您通常会提供给 shell 的参数。

您的代码可能如下所示:

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
}

子进程在死亡时会发送一个SIGCHLD 信号。从 POSIX 标准 (SUSv4) 引用的这段代码将处理:

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);
    }
}

【讨论】:

  • exec 不涉及 shell。假设 OP 想要运行 ls | grep -v hello。这将适用于系统,但不适用于 exec。
  • OP 可以将这些传递给 shell - 系统做同样的事情(但在幕后做另一个 forkexec)。
【解决方案3】:

试试这样的代码:

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

【讨论】:

  • 这让我觉得太快太脏了,因为这会从命令退出到 main 退出时创建一个僵尸进程。一个表现良好的 Unix 程序会希望避免这种情况。查看使用waitpid的其他答案。
【解决方案4】:

system ("command &amp;") 简单地放大命令怎么样?

【讨论】:

    猜你喜欢
    • 2014-03-06
    • 2013-03-12
    • 1970-01-01
    • 2019-02-17
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多