c - shell脚本中的后台进程收到EOF

标签 c shell stdin system-calls background-process

很难解释这种行为,所以这里有一个可重现的例子(在 macOS 上测试过)。

首先,我有以下 C 文件。细节并不重要,但我基本上使用了 read system call从标准输入读取 16 个字节,或者直到遇到 EOF。请注意,read 将在 EOF 处返回 0。

// test.c

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

int main() {
    char buf[1];
    for (int i = 0; i < 16; i++) {
        if (read(STDIN_FILENO, buf, 1) == 0) {
            printf("EOF encountered! Number of bytes read: %d\n", i);
            return 0;
        }
    }
    printf("Read all 16 bytes\n");
    return 0;
}

假设我将这个文件编译成一个名为test 的二进制文件。这是正在运行的程序:

$ echo 'sixteen bytes!!' | ./test
Read all 16 bytes

$ echo '' | ./test
EOF encountered! Number of bytes read: 1

$ ./test # Waits for user input

有道理吗?我什至可以接受最后一条命令并将其作为后台进程运行(尽管这毫无用处):

$ ./test &
[1] 19204

[1]  + suspended (tty input)  ./test

假设我接受这条命令并将其放入以下 ​​shell 脚本(称为 huh.sh):

#!/bin/sh

./test &

当我运行这个 shell 脚本时,输出如下:

$ ./huh.sh

EOF encountered! Number of bytes read: 0

这意味着 read 立即遇到 EOF,并且这只发生在 shell 脚本的上下文中。

如果我将 test 替换为另一个对 EOF 敏感的程序,我会看到类似的行为。例如,如果我直接在终端中运行 node &,我将能够在 ps 的输出中看到 node 进程.但是,如果我在 shell 脚本中运行 node &,它会立即退出。

谁能解释一下?

最佳答案

作业控制在交互式 shell 中默认启用,但在 shell 脚本中默认禁用。这是一个相关的引用from POSIX :

If job control is disabled (see set, -m), the standard input for an asynchronous list, before any explicit redirections are performed, shall be considered to be assigned to a file that has the same properties as /dev/null. This shall not happen if job control is enabled.

关于c - shell脚本中的后台进程收到EOF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64999542/

相关文章:

Docker:执行shell脚本时出现错误代码127

cygwin - 如何从标准输入使用 cp?

c - 在c中获取文件中每一行的值

c - 我如何像 scanf() 一样使用 getchar()?

shell - 如何使用shell脚本一次运行多个jar文件?

mysql - bash - SQL 查询输出到变量

c - 如何在 C (GCC) 中只获取整数?

c - dup2、stdout 和 stderr 出现问题

编译 -ansi -pedantic -Wall 自动切换 gcc

c++ - 在 C++ 中,自定义头文件是可选的吗?