たとえば、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
これはバグで、bash
4.4で修正されました。
command_not_found_handle()
フック(コマンドが見つからないときに呼び出される)を定義すると、bash
次のような場合でもフォアグラウンドにインポートされます。命令が見つかりませんバックグラウンドで始まります。
その後、時間の経過とともにcommand_not_found_handle
ttyデバイスをフォアグラウンドにインポートした後、シェルがttyデバイスからコマンドラインを読み取ると、バックグラウンドプロセスがターミナルデバイスから読み取ってSIGTTINを無視したときに発生するのと同じread()
エラーが返されます。EIO
信号。
bash
として扱われるファイルの終わりユーザーが入力している間、まるで押したかのように表示されます。Ctrl+D
次の手順で問題を再現できます。
$ command_not_found_handle() { sleep 20; }
$ a &
$ x
read()
もう始まったので初めて成功しても今後フォアグラウンドにインポートした後、command_not_found_handle
2回目以降の読み取りはx
失敗し、シェルは終了します。
Ubuntuではデフォルトで利用可能ですcommand_not_found_handle
。
$ a & true &
true
また、戻り時にSIGCHLDが最初のシェルを停止read()
し、2番目のシェルがまだフォアグラウンドで実行されているハンドラで起動するため、シェルは終了します。
しかし、通常、このバグが発生する可能性はほとんどありません。プロンプトを作成する前にシェルも前景として表示されるので、適切な瞬間に(メインシェルプロセスがインポートされた後)前景として表示される必要があるためです。command_not_found_handle
自分をフォアグラウンドにインポートします(tcsetpgrp()
フォアグラウンドを実行し、ttyデバイスから読み取りを開始します)。
この問題は2015年4月に解決されました。今回提出してください(CWRU.logの4/23エントリ)は次のとおりです。Valentin Bajramiは関連する問題について報告します。。