Reputation: 31
#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);
then the result displays on screen and if I try this 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
?
Upvotes: 1
Views: 3271
Reputation: 1239
When you write the following command in a shell
ls -l | sort
two programs are executed: ls
and sort
.
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.
So when you write
execlp("ls" , "ls", "-l", "|" , "sort", NULL);
it doesn't make any sense since |
and sort
are not parameters of ls
.
What you want is do what the shell does for you:
make a fork where you redirect stdout to your pipe (with dup) and execute ls
:
execlp("ls" , "ls", "-l", NULL);
make a fork where you redirect your pipe to stdin and execute sort
:
execlp("sort" , "sort", NULL);
close your pipe, wait, etc.
Upvotes: 2
Reputation: 512
There is a simple way of doing this. It involves using function 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.
Upvotes: 1
Reputation: 148890
Oups, you a making a confusion. exec...
family functions allow execution of one single program replacing the caller one. So your program just execute ls
command with "-l"
, "|"
, "sort"
as parameters.
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
in a shell, the |
is interpreted by the shell. And the shell :
ls -l
as a first commandsort
as a second commandYou 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.
Alternatively, you can ask the shell to do the job :
execlp("/bin/sh" , "sh", "-c", "ls -l | sort", NULL);
Upvotes: 2
Reputation: 361585
Piping is a shell construct. execlp()
isn't subject to shell parsing; 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
.
Upvotes: 2