【问题标题】:Why does write() call not display output on terminal when program is run in background via Makefile?当程序通过 Makefile 在后台运行时,为什么 write() 调用不会在终端上显示输出?
【发布时间】:2017-03-20 07:42:10
【问题描述】:

这是我的程序foo.c

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

int main()
{
    int i;
    printf("foo\n");
    write(0, "bar\n", 4);
    return 0;
}

如果我在前台或后台运行程序,foobar 都会打印在终端上。

$ gcc foo.c
$ ./a.out 
foo
bar
$ ./a.out &
[1] 2081
$ foo
bar

[1]+  Done                    ./a.out

但是当我通过Makefile 运行程序时,我看到bar 仅在程序在前台运行时打印。当程序在后台运行时,它不会在终端上打印出来。

这是我的Makefile 的样子。

fg:
        gcc foo.c
        ./a.out
        sleep 1

bg:
        gcc foo.c
        ./a.out &
        sleep 1

这是输出。

$ make fg
gcc foo.c
./a.out
foo
bar
sleep 1
$ make bg
gcc foo.c
./a.out &
sleep 1
foo
$

程序通过Makefile在后台运行时,为什么终端不打印bar

【问题讨论】:

  • write(0, 你确定要写信给stdout

标签: c makefile terminal background system-calls


【解决方案1】:

您的程序正在使用write() 系统调用写入标准输入。不保证您可以这样做,也不保证当您这样做时,它会出现在终端上。

很可能,make 提供了/dev/null 作为标准输入,因此当您的程序尝试写入它时,它要么失败(不为写入而打开),要么成功地写入黑洞。

当我将foo.c中的代码修改为:

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

int main(void)
{
    if (printf("foo\n") != 4)
        fprintf(stderr, "Failed to write 4 bytes to standard output\n");
    if (write(0, "bar\n", 4) != 4)
        fprintf(stderr, "Failed to write 4 bytes to standard input\n");
    return 0;
}

然后用make bg运行它,我得到:

$ make bg
gcc foo.c
./a.out &
sleep 1
Failed to write 4 bytes to standard input
foo
$

【讨论】:

  • 确实,这是我的程序中的错误。如果我将write(0 修复为write(1,问题就解决了。现在我看到foobar 都打印有make bg。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-05
  • 2015-02-02
  • 2023-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多