简体   繁体   English

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

[英]Why doesn't execlp allow me to use a pipe?

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

What's going wrong? 怎么了 Please help. 请帮忙。

If I write this: execlp("ls" , "ls", "-l", NULL); 如果我这样写: execlp("ls" , "ls", "-l", NULL); then the result displays on screen and if I try this execlp("ls" , "ls", "-l", "|" , "sort", NULL); 然后结果显示在屏幕上,如果我尝试使用此execlp("ls" , "ls", "-l", "|" , "sort", NULL); screen displays error message cannot access . 屏幕显示错误消息无法访问

Why? 为什么? Does anyone have any idea? 有人有什么主意吗? Why doesn't it allow me to use pipe ( | ) when I execute the command execlp ? 为什么在执行命令execlp时不允许使用管道( | )?

Piping is a shell construct. 管道是壳结构。 execlp() isn't subject to shell parsing; execlp()不受shell解析; it passes the arguments directly to the named command. 它将参数直接传递给命名命令。 To get shell features you need to explicitly start a shell process. 要获得外壳功能,您需要显式启动外壳过程。

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

In that case it's probably best to specify the absolute path to the shell /bin/sh , which means you can use execl instead of execlp . 在这种情况下,最好指定外壳程序/bin/sh的绝对路径,这意味着您可以使用execl而不是execlp

Oups, you a making a confusion. 糟糕,您感到困惑。 exec... family functions allow execution of one single program replacing the caller one. exec...家庭功能允许执行一个单独的程序来代替调用方。 So your program just execute ls command with "-l" , "|" 因此,您的程序只需使用"-l""|"执行ls命令 , "sort" as parameters. "sort"作为参数。

Here is what it gives interactively : 这是它交互式提供的内容:

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

On the other end, then you execute normaly ls -l | sort 在另一端,然后执行normals ls -l | sort ls -l | sort in a shell, the | 在外壳中ls -l | sort| is interpreted by the shell . 由shell解释 And the shell : 外壳

  • starts ls -l as a first command 启动ls -l作为第一个命令
  • starts sort as a second command 开始sort作为第二个命令
  • with output of first command connected to input of second. 将第一个命令的输出连接到第二个输入。

You can do that explicitely with the help of fork , pipe and execlp , but you will have to prepare the pipe, and explicitely fork in order to have 2 processes. 您可以在forkpipeexeclp的帮助下显式地执行此操作,但是您必须准备管道,并且显式地进行fork才能具有2个进程。

Alternatively, you can ask the shell to do the job : 另外,您可以要求外壳程序执行此操作:

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

When you write the following command in a shell 当您在shell中编写以下命令时

ls -l | sort

two programs are executed: ls and sort . 执行两个程序: lssort

The pipe character ( | ) means that the output of the first should be redirected to the standard input of the second. 竖线字符( | )表示第一个的输出应重定向到第二个的标准输入。 This pipe is interpreted by your shell. 此管道由您的外壳程序解释。 It is not a parameter of your command. 它不是命令的参数。

execlp takes the name of your program and its parameters as arguments. execlp将程序的名称及其参数作为参数。

So when you write 所以当你写

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

it doesn't make any sense since | 因为| and sort are not parameters of ls . sort不是ls参数。

What you want is do what the shell does for you: 您想要做的是shell为您做的事情:

  1. declare a pipe 声明管道
  2. make a fork where you redirect stdout to your pipe (with dup ) and execute ls : 做一个fork,将stdout重定向到管道(使用dup ),然后执行ls

     execlp("ls" , "ls", "-l", NULL); 
  3. make a fork where you redirect your pipe to stdin and execute sort : 做一个分支,将管道重定向到stdin并执行sort

     execlp("sort" , "sort", NULL); 
  4. close your pipe, wait, etc. 关闭管道,等待,等等。

There is a simple way of doing this. 有一个简单的方法可以做到这一点。 It involves using function popen : 它涉及使用函数popen

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

int main() {

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

    pclose(out);

    return 0;  
}

However it might be not what you were going for as it doesn't use exec. 但是,这可能不是您想要的,因为它不使用exec。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM