-1

I am trying to redirect output of ls command to a file fout.txt But file fout.txt contains only Here is the output

Below is my program:

int fout, ferr;
char *tok[3];
tok[0] = "ls", tok[1] = ">", tok[2] = "fout.txt";
fout = open("fout.txt", O_RDWR|O_CREAT|O_APPEND, 0600);
ferr = open("ferr.txt", O_RDWR|O_CREAT|O_APPEND, 0600);
puts("Here is the output\n");
execvp(tok[0], tok);
close(fout);
close(ferr);

Please help here.

Daniel Jour
  • 15,896
  • 2
  • 36
  • 63
Vinanti
  • 1
  • 1
  • On what operating system are you running this? – Daniel Jour Aug 10 '15 at 19:56
  • Also, are you sure that you're using `puts` and not `fputs` with `fout`? – Daniel Jour Aug 10 '15 at 20:01
  • You don't check the return value of execvp(). Possibly failed due to file fout.txt being currently open by another process (your program). – FredK Aug 10 '15 at 20:18
  • 1
    possible duplicate of [In C how do you redirect stdin/stdout/stderr to files when making an execvp() or similar call?](http://stackoverflow.com/questions/14543443/in-c-how-do-you-redirect-stdin-stdout-stderr-to-files-when-making-an-execvp-or) – Mike Andrews Aug 10 '15 at 20:28
  • How could the file not be empty? You never write to it! But you should see at least `ls: >: No such file or directory` somewhere... – Serge Ballesta Aug 10 '15 at 20:28
  • @SergeBallesta yes, I am getting the error ls: >: No such file or directory in file ferr.txt – Vinanti Aug 11 '15 at 04:08
  • @DanielJour here are my OS details: [user@cs-lb-66 ~]$ uname -a Linux cs-lb-66.cse.iitkgp.ernet.in 2.6.32-504.3.3.el6.centos.plus.i686 #1 SMP Tue Dec 16 23:15:00 UTC 2014 i686 i686 i386 GNU/Linux I am using puts and the string "Here is the output" along with file name (i.e. fout.txt) is getting written in file fout.txt – Vinanti Aug 11 '15 at 04:11

2 Answers2

4

Redirection such as you are attempting is not done directly via execvp() call. It's done in bash like this:

/* Execute a simple command that is hopefully defined in a disk file
   somewhere.

   1) fork ()
   2) connect pipes
   3) look up the command
   4) do redirections
   5) execve ()
   6) If the execve failed, see if the file has executable mode set.
   If so, and it isn't a directory, then execute its contents as
   a shell script.

   Note that the filename hashing stuff has to take place up here,
   in the parent.  This is probably why the Bourne style shells
   don't handle it, since that would require them to go through
   this gnarly hair, for no good reason.

Note the "connect pipes".

(This is not meant to be a complete answer - the questioner should be required to research something...)

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
4

The different redirections characters (< > >> |)are interpreted by the shells. As you ask a direct execvp execution, you just execute ls command with parameters > and fout.txt.

When I do that I get on stderr:

ls: >: No such file or directory
ls: fout.txt: No such file or directory

To redirect with the exec family of function you must explicitely open the files and use dup2 to connect them to stdin (0), stdout(1) and/or stderr(2) as shown in In C how do you redirect stdin/stdout/stderr to files when making an execvp() or similar call?

Community
  • 1
  • 1
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252