【问题标题】:execvp shell command with shell output redirection does not work带有 shell 输出重定向的 execvp shell 命令不起作用
【发布时间】:2021-04-20 13:55:48
【问题描述】:

我开发了以下代码: 主要:

#include<stdio.h>
#include<unistd.h>

int main()
{
    char *const args[] = {"/bin/ls", "> test.txt 2>&1", NULL};
    execvp(args[0], args);

    /* If this is reached execvp failed. */

    perror("execvp");
    return 0;
}

我需要执行这个 shell 命令:/bin/ls &gt; test.txt 2&gt;&amp;1 但我有一个错误:

$gcc -o main main.c 
$ vi main.c
$ gcc -o main main.c 
$ ./main 
/bin/ls: cannot access '> test.txt 2>&1': No such file or directory
$ 

为什么它返回 /bin/ls: cannot access '&gt; test.txt 2&gt;&amp;1': No such file or directory ?你有解决方案吗?

【问题讨论】:

    标签: c linux execvp


    【解决方案1】:

    不,那是行不通的。重定向是你的 shell 的一个功能。通过使用exec 函数之一,您可以完全绕过shell。所以你需要自己处理重定向。

    int out = open("test.txt", O_WRONLY | O_CREAT, 0644);
    dup2(out, 1);
    dup2(out, 2);
    close(out);
    execvp(args[0], args);
    

    但先将第二项放在 args 中。

    这将打开输出文件并将其复制到标准输入和标准输出,就像 shell 一样。最后关闭不再需要的原始描述符。

    我省略了错误检查,但你当然应该添加它。

    【讨论】:

    • 首先,您缺少mode 参数,因此您的open() 调用应该类似于open("test.txt", O_WRONLY | O_CREAT, 0644);。本着完整性的精神,生产质量的实现将对所有调用执行错误检查,dup() 并至少保存stderr,因此如果excevp() 失败,则可以将错误消息写入原始@987654329 @.
    • @AndrewHenle,我确实忘记了模式参数。我编辑了答案以包含它。
    【解决方案2】:

    重定向由 shell 解释。但是 execvp() 不运行 shell。它运行一个可执行文件。您可以通过调用“sh -c”来执行system() 内部完成的操作:

    #include<stdio.h>
    #include<unistd.h>
    
    int main(void)
    {
        char *const args[] = {"/bin/sh", "-c", "/bin/ls > test.txt 2>&1", NULL};
        execvp(args[0], args);
    
        /* If this is reached execvp failed. */
    
        perror("execvp");
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-05-16
      • 1970-01-01
      • 1970-01-01
      • 2015-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多