为什么没有execlp允许我使用管道?

时间:2015-05-21 20:43:58

标签: c unix pipe exec

#include <stdio.h>
#include <unistd.h>
main()
{
    execlp("ls" , "ls", "-l", "|" , "sort", NULL);    
}

出了什么问题?请帮忙。

如果我写这个:execlp("ls" , "ls", "-l", NULL);然后结果显示在屏幕上,如果我尝试这个execlp("ls" , "ls", "-l", "|" , "sort", NULL);屏幕显示错误消息无法访问

为什么呢?有谁有想法吗?为什么我执行命令|时不允许我使用管道(execlp)?

4 个答案:

答案 0 :(得分:2)

管道是一种壳结构。 execlp()不受shell解析;它将参数直接传递给命名命令。要获得shell功能,您需要显式启动shell进程。

execl("/bin/sh", "/bin/sh", "-c", "ls -l | sort", NULL);

在这种情况下,最好指定shell /bin/sh的绝对路径,这意味着您可以使用execl代替execlp

答案 1 :(得分:2)

Oups,你是一个混乱的人。 exec...系列函数允许执行一个单独的程序替换调用者。因此,您的程序只需执行ls命令,"-l""|""sort"作为参数。

以下是交互式提供的内容:

$ ls "-l" "|" "sort"
ls: sort: No such file or directory
ls: |: No such file or directory

另一方面,您在shell中执行normaly ls -l | sort| 由shell解释 shell

  • 启动ls -l作为第一个命令
  • 启动sort作为第二个命令
  • 输出第一个命令连接到第二个输入。

您可以在forkpipeexeclp的帮助下明确地执行此操作,但您必须准备管道,并明确地分叉以便有2个进程。< / p>

或者,您可以要求shell执行此任务:

execlp("/bin/sh" , "sh", "-c", "ls -l | sort", NULL);

答案 2 :(得分:2)

在shell中编写以下命令时

ls -l | sort

执行了两个程序:lssort

管道符(|)表示第一个的输出应重定向到第二个的标准输入。此管道由您的shell解释。它不是您命令的参数。

execlp将您的程序名称及其参数作为参数。

所以当你写

execlp("ls" , "ls", "-l", "|" , "sort", NULL);

它没有任何意义,因为|sort不是ls的参数。

你想做的是做shell为你做的事情:

  1. 声明pipe
  2. 制作一个用于将stdout重定向到管道的分叉(使用dup)并执行ls

    execlp("ls" , "ls", "-l", NULL);
    
  3. 制作一个fork,将管道重定向到stdin并执行sort

    execlp("sort" , "sort", NULL);
    
  4. 关闭你的烟斗,等等等。

答案 3 :(得分:1)

有一种简单的方法可以做到这一点。它涉及使用函数popen

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

int main() {

    FILE* out  = popen("ls -l | sort", "w");

    pclose(out);

    return 0;  
}

然而,它可能不是你想要的,因为它没有使用exec。