execvp shell command with shell output redirection does not work

I have developed the following code: main:

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

I need to execute this shell command : /bin/ls > test.txt 2>&1 but I have got an error:

$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
$ 

Why it returns /bin/ls: cannot access '> test.txt 2>&1': No such file or directory ? Have you a solution to fix that ?

Upvotes: 1

Views: 182

Answers (2)

koder
koder

Reputation: 2093

no that doesn't work. Redirecting is a function of your shell. And by using one of the exec functions, you bypass the shell completely. So you need to handle redirection yourself.

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

but drop the second item in args first.

This will open the output file and duplicate it to stdin and stdout like the shell would do. Finally close the original descriptor as that is no longer needed.

I left out error checking, but you should definitely add that of course.

Upvotes: 4

Rachid K.
Rachid K.

Reputation: 5211

Redirections are interpreted by the shell. But execvp() does not run a shell. It runs an executable. You can do what is done internally by system() by calling "sh -c":

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

Upvotes: 1

Related Questions