백그라운드 작업을 스크립트에 넣으면 스크립트 및 스크립트 호출자가 종료된 후에도 작업이 유지되는 이유는 무엇입니까?

백그라운드 작업을 스크립트에 넣으면 스크립트 및 스크립트 호출자가 종료된 후에도 작업이 유지되는 이유는 무엇입니까?

lxterminal 내에서 실행되는 대화형 bash 셸에서 백그라운드 작업을 실행하는 경우

$ evince &

그런 다음 셸을 닫으면 백그라운드 작업이 종료됩니다.

배경 명령을 스크립트에 넣고 대화형 bash 셸에서 스크립트를 실행하는 경우:

$ cat test.sh 
!# /bin/bash

evince &
$ ./test.sh
$

스크립트가 종료된 후에도 백그라운드 작업은 계속 실행 중입니다. 대화형 bash 셸을 종료한 후에도 백그라운드 작업은 계속 실행됩니다.

백그라운드 작업을 스크립트에 넣고 스크립트를 실행하면 스크립트 종료와 스크립트 호출자의 종료 모두에서 작업이 유지되는 이유가 궁금합니다. 작업을 스크립트로 래핑하는 것이 스크립트가 종료되고 스크립트를 호출하는 셸이 종료되어도 작업이 유지되도록 하는 좋은 방법일까요?

감사해요.

답변1

  1. "쉘 닫기"는 창을 닫는 것을 의미한다고 생각합니다 lxterminal . 상호 작용 lxterminal과 상호 작용은 bash커널 수준 구성인 의사 TTY 장치를 통해 서로 연결됩니다.

    bash대화형 하위 프로세스가 계속 실행되는 동안 이 작업을 수행하면 lxterminal프로세스가 의사 TTY 측을 닫습니다. 이로 인해 커널은 SIGHUP 신호를 상호 작용에 보냅니다 bash.

    이것신호이 장에서는 다음과 같이 man bash말합니다.

    기본적으로 쉘은 SIGHUP을 수신한 후 종료됩니다. 대화형 셸은 종료하기 전에 실행 중이거나 중지된 모든 작업에 SIGHUP을 다시 보냅니다. 중지된 작업은 SIGHUP을 수신할 수 있도록 SIGCONT로 전송됩니다.

    쉘이 특정 작업에 신호를 보내는 것을 방지하려면 disown내장 명령(아래 쉘 내장 명령 참조)을 사용하여 작업 테이블에서 해당 작업을 제거하거나 내장 명령을 사용하여 SIGHUP을 수신하지 않는 것으로 표시해야 합니다 disown -h.

    SIGHUP 신호의 예상되는 의미는 "사용자 터미널에 대한 연결이 끊어졌습니다. 필요한 경우 저장되지 않은 작업을 저장하고 순서대로 종료하십시오."입니다. (데몬의 경우 이는 적용되지 않으므로 신호는 일반적으로 "구성 파일 다시 읽기" 및/또는 "로그 회전을 위해 로그 파일을 닫았다가 다시 열기"를 의미하는 데 사용됩니다.)

    매뉴얼 페이지에 명시된 대로 상호 작용은 bashSIGHUP 신호를 모든 하위 항목에 다시 보냅니다(사용법에서 달리 지정하지 않는 한 disown). 이것이 배경이 종료되는 원인입니다 evince.

  2. 하지만스크립트를 사용할 때, 대화형 쉘은 fork()새 프로세스에서 쉘을 실행하여 스크립트를 실행한 다음 스크립트를 실행하는 새 쉘이 fork()다시 실행됩니다 evince. 이후 스크립트가 종료되므로 스크립트를 실행한 셸이 종료됩니다.

    이 시점에서 evince프로세스에는 더 이상 상위 프로세스가 없습니다. 그러나 목록을 보면 ps -efPPID 필드가 비어 있는 프로세스는 절대 없습니다.프로세스는 상위 프로세스를 가질 수 없습니다.. 따라서 이 상황을 처리하기 위해 커널은 evince고아 프로세스에 PPID 1을 할당하여 이 프로세스의 채택된 하위 프로세스로 만듭니다 init. 이제 원래 상호 작용은 스크립트를 실행하는 인스턴스가 실제로 다른 프로세스를 시작했다는 사실 bash을 알지 못합니다 . 이 지식은 스크립트를 실행하는 셸 인스턴스와 함께 사라집니다.bash

    따라서 상호작용은 세션이 끝날 때 SIGHUP을 보내야 할 프로세스가 bash있다는 사실을 전혀 모릅니다 .evince

    이 스크립트를 통해 달성하는 것은 실제로 의도적으로 사용된 기술의 기본 버전입니다.악마 프로세스라고 합니다.더블 포크. (데몬화 = 이를 시작한 프로세스 및 세션과 완전히 독립적으로 만듭니다.)

    보시다시피 이는 실제로 이 evince 프로세스를 대화형 프로세스와 별도로 유지하는 데 충분 bash하지만 여전히 GUI 로그인 세션의 일부로 유지됩니다. 그러나 전체 데몬을 원한다면 두 번째 분기 전에 몇 가지 추가 단계를 수행해야 합니다.

    • 표준 입력, 표준 출력 및 표준 오류가 다음으로 리디렉션되는지 확인하십시오./dev/null
    • 다른 파일 설명자가 열려 있으면 닫습니다.
    • cd /이렇게 하면 프로세스가 실제로 특정 파일 시스템의 파일에 액세스해야 하는 경우를 제외하고는 프로세스가 파일 시스템 마운트/마운트 해제를 실수로 방해하지 않습니다.
    • umask원하는/필요한 값으로 명시적으로 설정
    • setsid명령을 사용할 수 있는 경우 이를 사용하여 생성된 프로세스를 세션 프로세스 그룹에서 연결 해제하고 완전히 독립적으로 만들어야 합니다(즉, evince &스크립트 끝에서 대신 사용할 수 있음 exec setsid evince).

    Bash 셸의 데몬에 대한 자세한 설명은 여기를 참조하세요.http://blog.n01se.net/blog-n01se-net-p-145.html

답변2

무료 프로그램을 종료하면 해당 프로그램이 로그아웃 프로필에 있을 수 있음을 나타냅니다.

백그라운드 작업을 실행하는 셸이 이미 완료되어 있고 입력을 통해 동일한 효과를 얻을 수 있으므로 스크립트를 사용하면 효과적입니다.

( evince & )

그러면 백그라운드에 표시된 하위 쉘이 시작된 다음 종료됩니다. evince는 이제 데몬입니다.

관련 정보