获取`posix_spawn`的输出

nbu*_*bis 9 c posix fork

所以我可以使用 POSIX 在 Unix/Linux 中运行一个进程,但是有什么方法可以将进程的 STDOUT 和 STDERR 存储/重定向到一个文件?该spawn.h头包含减速posix_spawn_file_actions_adddup2看起来相关,但我不知道怎么和使用它。

进程产生:

posix_spawn(&processID, (char *)"myprocess", NULL, NULL, args, environ);

输出存储:

...?

mur*_*uru 16

这是修改衍生进程的文件描述符的最小示例,保存为foo.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <spawn.h>

int main(int argc, char* argv[], char *env[])
{
    int ret;
    pid_t child_pid;
    posix_spawn_file_actions_t child_fd_actions;
    if (ret = posix_spawn_file_actions_init (&child_fd_actions))
        perror ("posix_spawn_file_actions_init"), exit(ret);
    if (ret = posix_spawn_file_actions_addopen (&child_fd_actions, 1, "/tmp/foo-log", 
            O_WRONLY | O_CREAT | O_TRUNC, 0644))
        perror ("posix_spawn_file_actions_addopen"), exit(ret);
    if (ret = posix_spawn_file_actions_adddup2 (&child_fd_actions, 1, 2))
        perror ("posix_spawn_file_actions_adddup2"), exit(ret);

    if (ret = posix_spawnp (&child_pid, "date", &child_fd_actions, NULL, argv, env))
        perror ("posix_spawn"), exit(ret);
}
Run Code Online (Sandbox Code Playgroud)

它有什么作用?

  • 的第三个参数posix_spwan是一个类型的指针posix_spawn_file_actions_t(你给出的一个NULL)。posix_spawn将打开、关闭或复制从posix_spawn_file_actions_t对象指定的调用进程继承的文件描述符。
  • 所以我们从一个posix_spawn_file_actions_t对象 ( chiild_fd_actions) 开始,并用posix_spawn_file_actions_init().
  • 现在,这些posix_spawn_file_actions_{addopen,addclose,addup2}函数可分别用于打开、关闭或复制文件描述符(在open(3),close(3)dup2(3)函数之后)。
  • 所以我们posix_spawn_file_actions_addopen/tmp/foo-log文件描述符1(又名标准输出)中创建了一个文件。
  • 然后我们posix_spawn_file_actions_adddup2fd 2(aka stderr) 到 fd 1。
  • 需要注意的是什么已经打开或欺骗还没有。最后两个函数只是简单地更改了child_fd_actions对象,以说明要执行这些操作。
  • 最后,我们使用posix_spawnchild_fd_actions对象。

测试一下:

$ make foo
cc     foo.c   -o foo
$ ./foo
$ cat /tmp/foo-log 
Sun Jan  3 03:48:17 IST 2016
$ ./foo +'%F %R'  
$ cat /tmp/foo-log
2016-01-03 03:48
$  ./foo -d 'foo'  
$ cat /tmp/foo-log
./foo: invalid date ‘foo’
Run Code Online (Sandbox Code Playgroud)

如您所见,衍生进程的 stdout 和 stderr 都转到了/tmp/foo-log.