为什么使用“&”运行无效进程会关闭终端?

为什么使用“&”运行无效进程会关闭终端?

例如,a&在 bash 中运行时,终端窗口会关闭,我希望在其中启动一个新进程,然后出现一条错误消息(类似于,例如grep &)。

是什么导致了这种行为?是故意的吗?

编辑:根据要求,

yuvalw@UX410UQK:~$ echo $-
himBH

我还尝试在 bash 中打开另一个 bash 以获得额外的输出。我的输入bash后面是a&几行新行:

yuvalw@UX410UQK:~$ bash
yuvalw@UX410UQK:~$ a&
[1] 15323
yuvalw@UX410UQK:~$ exit
yuvalw@UX410UQK:~$ a: command not found

yuvalw@UX410UQK:~$

再次调用a&将关闭终端窗口。

编辑2:更多回声

yuvalw@UX410UQK:~$ echo "$BASH_VERSION $SHELLOPTS $BASHOPTS"
4.3.48(1)-release braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:progcomp:promptvars:sourcepath

陷阱:

yuvalw@UX410UQK:~$ trap
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU

类型退出:

yuvalw@UX410UQK:~$ type exit
exit is a shell builtin

PROMPT_COMMAND(空):

yuvalw@UX410UQK:~$ echo $PROMPT_COMMAND

PS1:

yuvalw@\UX410UQK:~$ echo $PS1
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$

编辑3:打开一个新终端,似乎没有发生这种情况,我可以运行a&得很好,但经过cd一段时间后,问题又回来了。在这两种情况下,command_not_found_handle 看起来是相同的。

yuvalw@yuvalw-UX410UQK:~$ type command_not_found_handle

command_not_found_handle is a function
command_not_found_handle () 
{ 
    if [ -x /usr/lib/command-not-found ]; then
        /usr/lib/command-not-found -- "$1";
        return $?;
    else
        if [ -x /usr/share/command-not-found/command-not-found ]; then
            /usr/share/command-not-found/command-not-found -- "$1";
            return $?;
        else
            printf "%s: command not found\n" "$1" 1>&2;
            return 127;
        fi;
    fi
}

答案1

这是一个错误bash,已在 4.4 中修复。

如果您command_not_found_handle()定义了钩子(在未找到命令时调用该钩子),bash则将其置于前台,即使未找到命令是在后台启动的。

然后,根据时间的不同,如果 shell 在command_not_found_handle将 tty 设备置于前台后从 tty 设备读取命令行,read()则会返回错误EIO,就像后台进程从终端设备读取并忽略 SIGTTIN 信号时发生的情况一样。

bash会将其视为文件结尾在用户输入时就好像您按下了Ctrl+D

可以通过执行以下操作来重现该问题:

$ command_not_found_handle() { sleep 20; }
$ a &
$ x

即使第一次read()成功,因为它已经开始command_not_found_handle置于前台,按下后的第二次和后续读取x将失败并导致 shell 退出。

Ubuntu 上默认command_not_found_handle提供,

$ a & true &

还会导致 shell 退出,因为true返回时的 SIGCHLD 会中断第一个read(),并导致第二个 shell 启动,处理程序仍在前台运行。

然而,在一般情况下,该错误似乎不太可能触发,因为 shell 在编写提示符之前也会将自己置于前台,因此必须在正确的时刻(在主 shell 进程将command_not_found_handle自己置于前台之后)将自己置于前台(执行)tcsetpgrp()前台和开始从 tty 设备读取之前)。

该问题已于 2015 年 4 月修复这次提交(CWRU.log 中的 4/23 条目)如下Valentin Bajrami 对相关问题的报告

相关内容