1

In the linux terminal, I can type

echo hello! > /path/to/file

I thought I would be able to do the same thing using execv:

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

int main(void){
    char *write_cmd[] = { "echo", "hello!", ">", "/path/to/file", NULL};
    if (fork() == 0){
        execv("/bin/echo", write_cmd);
    }
    else{
        sleep(1);
    }
    return 0;
}

However, this code doesn't write 'hello!' to the file, which is what I want it to do. Is there another way to do this using execv and echo?

Edit: I've tried using dup2 as a solution as well: #include #include #include

int main(void){
    char *write_cmd[] = { "echo", "hello!", NULL };
    if (fork() == 0){
        int tmpFd = open("/path/to/file", O_WRONLY);
        dup2(tmpFd, 1);
        execv("/bin/echo", write_cmd);
        close(tmpFd);
        exit(0);
    }
    else{
        sleep(1);
    }
    return 0;
}

However, this doesn't give me the result I want either. This writes 'hello!' to the file, but it also overwrites everything else that was already written on the file. How can I guarantee that 'hello!' will be written to the END of the file?

Jay
  • 113
  • 5
  • The shell interprets it as the redirection-operator. As you execute the new program directly instead of asking the shell to do it on your behalf, you get to do the redirection manually. Look at `dup2`. – Deduplicator Feb 13 '15 at 00:10
  • Thanks for the response. I've tried using dup2. However, the problem is that I want to be able to always write to the END of the file. When I use dup2, I am only able to overwrite what is already written to the file. – Jay Feb 13 '15 at 00:16
  • Your `echo hello! > /path/to/file` overwrites the file. If you always want to append, please update the question to make that clear. The shell uses `>>` to append to a file. If you use what I suggested, you can pass `>>` rather than `>` to the shell. – Keith Thompson Feb 13 '15 at 00:20
  • the program needs to be executing a shell., 'echo' is just a command passed to a shell, not a standalone executable. suggest using 'system( "echo hello! >> /path/to/file" );' The '>>' appends to the file – user3629249 Feb 13 '15 at 00:21
  • 1
    The code in your question will not compile. You're missing a semicolon on the declaration of `write_cmd`, and `'>'` should be `">"`. Please include compilable code in your question (unless you're asking about a compile-time error). – Keith Thompson Feb 13 '15 at 00:21
  • Your edit is correct, and your note about it overwriting the file is the same as the shell does with `>`. If you want to append to the file (as the shell does if you use `>>`), open the file with `O_APPEND` in the flags. – Chris Dodd Feb 13 '15 at 01:05

2 Answers2

3

You can, but only indirectly.

The > redirection operator is interpreted by the shell; /bin/echo doesn't recognize it, and treats it as just another argument to be printed.

If you want the shell to do the redirection, you need to invoke /bin/sh and pass the entire command to it as an argument.

Untested code follows:

char *write_cmd[] = { "/bin/sh", "-c", "echo hello! > /path/to/file", NULL };
// ...
execv("/bin/sh", write_cmd);

Or, more simply, you could use system().

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
1

First of all, redirection operators like > are interpreted by the shell, and mean nothing to execve(2) (or to echo, for that matter). You could try using system(3) instead, or you could set up the redirection yourself by opening the output file and setting standard out to the resulting file descriptor using dup2(2) (see this question).

Secondly, write_cmd is an array of char*, but '>' (note the single quotes) has type int. This effectively means that you are putting an integer in an array that otherwise contains pointers to strings. You probably meant to write ">".

Community
  • 1
  • 1
Martin Törnwall
  • 9,299
  • 2
  • 28
  • 35
  • [system(3)](http://linux.die.net/man/3/system) was the best option. Thanks for your help! – Jay Feb 13 '15 at 00:31