「&」を使用して誤ったプロセスを実行すると、端末が閉じるのはなぜですか?

「&」を使用して誤ったプロセスを実行すると、端末が閉じるのはなぜですか?

たとえば、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(NULL):

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\]\$

a&編集3:新しい端末を開くと、これは起こらないようです。正常に実行できますが、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

これはバグで、bash4.4で修正されました。

command_not_found_handle()フック(コマンドが見つからないときに呼び出される)を定義すると、bash次のような場合でもフォアグラウンドにインポートされます。命令が見つかりませんバックグラウンドで始まります。

その後、時間の経過とともにcommand_not_found_handlettyデバイスをフォアグラウンドにインポートした後、シェルがttyデバイスからコマンドラインを読み取ると、バックグラウンドプロセスがターミナルデバイスから読み取ってSIGTTINを無視したときに発生するのと同じread()エラーが返されます。EIO信号。

bashとして扱われるファイルの終わりユーザーが入力している間、まるで押したかのように表示されます。Ctrl+D

次の手順で問題を再現できます。

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

read()もう始まったので初めて成功しても今後フォアグラウンドにインポートした後、command_not_found_handle2回目以降の読み取りはx失敗し、シェルは終了します。

Ubuntuではデフォルトで利用可能ですcommand_not_found_handle

$ a & true &

trueまた、戻り時にSIGCHLDが最初のシェルを停止read()し、2番目のシェルがまだフォアグラウンドで実行されているハンドラで起動するため、シェルは終了します。

しかし、通常、このバグが発生する可能性はほとんどありません。プロンプトを作成する前にシェルも前景として表示されるので、適切な瞬間に(メインシェルプロセスがインポートされた後)前景として表示される必要があるためです。command_not_found_handle自分をフォアグラウンドにインポートします(tcsetpgrp()フォアグラウンドを実行し、ttyデバイスから読み取りを開始します)。

この問題は2015年4月に解決されました。今回提出してください(CWRU.logの4/2​​3エントリ)は次のとおりです。Valentin Bajramiは関連する問題について報告します。

おすすめ記事