質問

     pid_t pid;
     pid=fork();
     if (pid == 0)
     {
         //child process.
         execl("/opt/bin/version.out", "version.out > /tmp/version",0);
         _exit(0);
     }
     else
     {
         // this is parent, wait for child to finish.
         waitpid(pid, NULL, 0);
         verDir("/tmp/version");
     }

With the above c++ code, I am trying to create a child process, execute command /opt/bin/version.out and redirect the output to /tmp/version, but it doesn't create /tmp/version at all, any error with above syntax? is execl() and waitpid() syntax correct? Thanks.

役に立ちましたか?

解決

The '>' redirection is not valid in execl as it is a shell command....

Try to look at Running a script from execl() for an example of how to invoke a shell to do your execution....

If you want to avoid the shell invokation, you will have to do a 'dup' call to close the stderr/stdout in the chiled process and open it to the file -- you can see an example here; fork, pipe exec and dub2

Or in your child process, you can force the output to a specific file, by closing the stdout and reopen it as the file, like this;

 if (pid == 0)
     {
         //child process.
         close(1);
         creat("/tmp/version",0644); // this will create a new stdout
         close(2);
         dup(1);   // this will make stderr to also go to the same file.....

         execl("/opt/bin/version.out", "version.out",0);
         perror("execl didn't work"); // print out the error if execl failed...
         _exit(0);
     }.....

他のヒント

Redirection is a shell function, not a kernel function. You could run your command through the shell:

execl("/bin/sh", "sh", "-c", "/opt/bin/version.out > /tmp/version", (char *)NULL);

As an easier alternative, you could use popen() to run /opt/bin/version.out and read its output directly into your program. You would not have to use /tmp/version in this case.

FILE *version = popen("/opt/bin/version.out", "r");
... read from version ...
pclose(version);

Instead of doing the redirection in the argument of execl (which is incorrect), it should be done as part of a dup2 call.

Here is a code snippet on how to redirect to a a file instead of stdout without any error checking.

 int fd = open ("/tmp/version", O_CREAT|O_WRONLY|O_TRUNC); 
 dup2(fd, STDOUT_FILENO); 
 close(fd); 

Now, you can launch your binary using execl

 execl("/opt/bin/version.out","version.out", (char*)0); 

Do please add appropriate error checking for existence of a file and access permissions.

You will need to run it in a shell:

execl("/bin/sh", "sh", "-c", "/opt/bin/version.out > /tmp/version", (char*)NULL);

You should also be checking the return value of execl for errors.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top