为什么从bash脚本调用超时程序会导致tcsetattr挂起?

时间:2017-01-31 02:50:47

标签: c linux bash shell timeout

由于某种原因调用超时程序,从bash脚本中将tcsetattr作为参数提供给程序会导致tcsetattr挂起。直接在终端中将其调用到bash脚本之外不会导致它挂起。为什么会这样?看https://github.com/coreutils/coreutils/blob/master/src/timeout.c,看起来好像没有任何文件描述符的超时混乱。看起来它被设置为忽略两个信号,但这里不应该相关。

以下是最小测试用例:

short.c

#include <stdio.h>
#include <termios.h>
#include <string.h>

int main() {
        struct termios tty;
        tcgetattr(0, &tty);
        fprintf(stderr, "Before tcsetattr");
        tcsetattr(0, TCSANOW, &tty);
        fprintf(stderr, "After tcsetattr");
}

simple_check.sh

#!/bin/bash
timeout 5 ./a.out < /dev/tty
echo $?

Bash输出

$ gcc short.c
$ bash simple_check.sh
Before tcsetattr
124 # Note this should output `After tcsetattr` if it was 'working'
$ timeout 5 ./a.out < /dev/tty
Before tcsetattr
After tcsetattr

潜在有用的信息

$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.1 LTS
Release:    16.04
Codename:   xenial

1 个答案:

答案 0 :(得分:1)

超时--foreground选项可能会避免此问题吗? 这会停止将超时(和孩子)放入他们自己的程序组。