"set -m"이 무엇을 하는지 자세히 설명해 줄 수 있는 사람이 있나요?

"set -m"이 무엇을 하는지 자세히 설명해 줄 수 있는 사람이 있나요?

존재하다매뉴얼 페이지, 그것은 단지 다음과 같이 말합니다:

-m은 작업 제어를 활성화합니다.

그런데 이것이 실제로 무엇을 의미하는가?

나는이 명령을 하나에서 발견했습니다.그래서 질문은, "패브릭이 tomcat을 시작할 수 없습니다"라는 OP와 동일한 문제가 있습니다. set -m문제를 해결했습니다 . OP가 조금 설명했지만 잘 이해가 되지 않습니다.

문제는 명령이 끝나면 종료되기 때문에 백그라운드 작업에 있습니다.

해결책은 간단합니다. 명령 앞에 "set -m;" 접두사를 추가하면 됩니다.

답변1

bash 문서 인용(에서 man bash):

JOB CONTROL
       Job  control  refers to  the  ability  to selectively  stop
       (suspend) the execution of  processes and continue (resume)
       their execution at a later point.  A user typically employs
       this facility via an interactive interface supplied jointly
       by the operating system kernel's terminal driver and bash.

따라서 매우 간단하게 (대화형 쉘의 기본값)을 사용하면 set -m및 (비대화형 쉘의 기본값)에서 비활성화되는 내장 기능을 사용할 수 있습니다.fgbgset +m

그러나 작업 제어와 종료 시 백그라운드 프로세스 종료 사이의 연결은 분명하지 않지만 하나가 있다는 것을 확인할 수 있습니다. set -m; (sleep 10 ; touch control-on) &해당 명령을 입력한 후 즉시 셸을 종료하면 run을 실행하면 파일이 생성되지만 set +m; (sleep 10 ; touch control-off) &충족되지는 않습니다.

나는 그 대답이 아래 문서의 나머지 부분에 있다고 생각합니다 set -m.

-m      Monitor  mode. [...]                     Background pro‐
        cesses run in a separate process group and a  line  con‐
        taining  their exit status is printed upon their comple‐
        tion.

이는 시작된 백그라운드 작업이 set +m실제 "백그라운드 프로세스"가 아니라는 것을 의미합니다("백그라운드 프로세스는 터미널의 프로세스 그룹 ID와 다른 프로세스 그룹 ID를 가진 프로세스입니다"). 해당 작업을 시작한 셸과 동일한 프로세스 그룹 ID를 공유합니다. 자체 프로세스 그룹 ID를 갖는 대신. 프로세스 그룹은 적절한 백그라운드 프로세스와 같습니다. 이것은 일부 백그라운드 작업 전에 셸이 종료될 때 관찰되는 동작을 설명합니다. 올바르게 이해했다면 종료할 때 셸과 동일한 프로세스 그룹에 있는 프로세스에 신호가 전송됩니다(따라서 에서 시작된 백그라운드 작업이 종료됨 set +m). 다른 프로세스 그룹의 프로세스(따라서 아래에서 시작된 실제 백그라운드 프로세스는 고려되지 않음 set -m)

따라서 귀하의 경우 startup.sh스크립트가 백그라운드 작업을 시작할 수 있습니다. 이 스크립트가 비대화형(예: 링크한 질문에서와 같이 SSH를 통해)으로 실행되면 작업 제어가 비활성화되고 "백그라운드" 작업이 원격 셸의 프로세스 그룹을 공유하므로 셸이 종료되면 종료됩니다. 대신 해당 셸에서 작업 제어를 활성화하면 백그라운드 작업이 자체 프로세스 그룹을 가져오고 상위 셸이 종료될 때 종료되지 않습니다.

답변2

github 문제 목록에서 이것을 찾았으며 이것이 귀하의 질문에 대한 답변이라고 생각합니다.

이는 실제로 SSH 문제는 아니지만 BASH 비대화형/대화형 모드 및 프로세스 그룹으로의 신호 전파를 둘러싼 미묘한 동작에 가깝습니다.

다음은 다음을 기반으로합니다. https://stackoverflow.com/questions/14679178/why-does-ssh-wait-for-my-subshells-without-t-and-kill-them-with-t/14866774#14866774 그리고http://www.itp.uzh.ch/~dpotter/howto/daemonize, 일부 가정은 아직 완전히 검증되지 않았지만 작동 방식에 대한 테스트는 확인된 것으로 보입니다.

pty/tty = 거짓

시작된 bash 쉘은 시작된 프로세스의 stdout/stderr/stdin에 연결되고 소켓에 아무것도 연결되지 않고 해당 하위 프로세스가 종료될 때까지 계속 실행됩니다. 좋은 데몬은 자식 프로세스가 종료될 때까지 기다리지 않고 자식 프로세스를 분기한 다음 종료하는지 확인합니다. 이 모드에서는 SSH를 통해 하위 프로세스로 SIGHUP이 전송되지 않습니다. 나는 이것이 자체 악마 제거를 처리하고 백그라운드에서 실행될 필요가 없는 프로세스를 실행하는 대부분의 스크립트에서 잘 작동할 것이라고 믿습니다. init 스크립트가 "&"를 사용하여 프로세스를 배경화하는 경우 주요 문제는 배경 프로세스가 stdin에서 읽으려고 시도하는 것일 수 있습니다. 이는 세션이 종료된 경우 SIGHUP을 트리거하기 때문입니다.

pty/tty = 참*

init 스크립트가 백그라운드에서 프로세스를 시작하면 상위 BASH 셸은 SSH 연결에 종료 코드를 반환합니다. 이는 하위 프로세스가 종료될 때까지 기다리지 않고 stdout/stderr에서 차단되지 않기 때문에 즉시 종료됩니다. /stdin. 이로 인해 SIGHUP이 상위 bash 쉘 프로세스 그룹으로 전송됩니다. 여기에는 bash의 비대화형 모드에서 작업 제어가 비활성화되어 있으므로 방금 시작된 하위 프로세스가 포함됩니다. 데몬이 포크될 때 또는 포크된 프로세스 내에서 새 프로세스 세션을 명시적으로 시작하는 경우 해당 데몬이나 해당 하위 프로세스는 기존 BASH 상위 프로세스로부터 SIGHUP을 수신하지 않습니다. 이는 SIGTERM이 표시되는 일시 중지된 작업과 다릅니다. 나는 이 문제가 때때로 약간의 경쟁 조건과 관련되어 있다고 생각합니다. 악마화에 대한 표준적인 접근 방식을 살펴보면— http://www.itp.uzh.ch/~dpotter/howto/daemonize, 상위 프로세스가 종료될 때까지 실행되지 않을 수 있는 포크된 프로세스에 의해 새 세션이 생성되어 위에서 설명한 무작위 성공/실패 동작이 발생하는 코드를 코드에서 볼 수 있습니다. sleep 문은 분기된 프로세스에 새 세션을 생성할 수 있는 충분한 시간을 제공하므로 경우에 따라 작동합니다.

pty/tty = true이고 bash에서 작업 제어를 명시적으로 활성화합니다.

SSH는 bash 쉘 또는 시작된 하위 프로세스의 stdout/stderr/stdin에 연결하지 않습니다. 즉, 상위 bash 쉘이 요청된 명령 실행을 시작하면 종료됩니다. 이 경우 작업 제어가 명시적으로 활성화되면 "&"를 사용하여 bash 셸에서 시작된 모든 프로세스는 즉시 별도의 세션에 들어가고 SIGHUP 신호(이 경우 SSH 연결)를 수신하지 않습니다.

고쳐야 할 것

이러한 솔루션은 백그라운드 프로세스/서비스를 사용할 때 특별한 경우로 run/sudo 작업 문서에서 명시적으로 언급되어야 한다고 생각합니다. 기본적으로 "pty=false"를 사용하거나 이것이 가능하지 않은 경우 첫 번째 명령으로 작업 제어를 명시적으로 활성화하면 동작이 올바르게 됩니다.

~에서https://github.com/fabric/fabric/issues/395

관련 정보