"&"를 사용하여 잘못된 프로세스를 실행하면 터미널이 닫히는 이유는 무엇입니까?

"&"를 사용하여 잘못된 프로세스를 실행하면 터미널이 닫히는 이유는 무엇입니까?

예를 들어, 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\]\$

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_handle두 번째 및 후속 읽기는 x실패하고 쉘이 종료됩니다.

Ubuntu에서는 기본적으로 사용 가능합니다 command_not_found_handle.

$ a & true &

true또한 반환 시 SIGCHLD가 첫 번째 쉘을 중단 read()하고 두 번째 쉘이 여전히 포그라운드에서 실행 중인 핸들러와 함께 시작되기 때문에 쉘이 종료됩니다 .

그러나 일반적으로 이 버그가 발생할 가능성은 거의 없습니다. 프롬프트를 작성하기 전에 쉘도 전경으로 나타나므로 적절한 순간에(메인 쉘 프로세스가 가져온 후) 전경으로 나타나야 하기 때문입니다. command_not_found_handle자신을 전경으로 가져옵니다( tcsetpgrp()전경을 실행하고 tty 장치에서 읽기 시작).

이 문제는 2015년 4월에 해결되었습니다.이번에 제출하세요(CWRU.log의 4/23 항목)은 다음과 같습니다.Valentin Bajrami가 관련 문제에 대해 보고합니다..

관련 정보