ssh -t
백그라운드 작업이 완료될 때까지 기다리면 어떨까요 ?
예:
ssh user@example 'sleep 2 &'
ssh가 2초 후에 반환되기 때문에 이는 예상대로 작동합니다.
ssh user@example -t 'sleep 2 &'
완료를 기다리지 않고 sleep
즉시 반환합니다.
누구든지 이것의 이유를 설명할 수 있습니까? ssh -t
반환하기 전에 모든 백그라운드 프로세스를 완료할 수 있는 방법이 있습니까 ?
내 사용 사례는 다음을 사용하여 스크립트를 시작 ssh -t
하고 해당 스크립트가 기본 스크립트가 완료된 후에도 활성 상태를 유지해야 하는 여러 백그라운드 작업을 시작하는 것입니다. 지금까지는 이것이 ssh -t
불가능했습니다.
답변1
그렇지 않은 경우 -t
두 개의 파이프를 통해 sshd
원격 쉘의 stdout(및 하위 쉘)과 stderr을 가져옵니다 sleep
(또한 다른 파이프를 통해 클라이언트의 입력을 보냅니다).
sshd
사용자의 로그인 셸을 시작한 프로세스를 기다리지만 해당 프로세스가 종료된 후 stdout 파이프(적어도 stderr 파이프가 아닌 openssh의 경우)에서 eof를 기다립니다.
eof는 파이프의 쓰기 측 프로세스에 대해 열려 있는 파일 설명자가 없을 때 발생합니다. 이는 일반적으로 stdout이 다른 것으로 리디렉션되지 않은 모든 프로세스가 사라진 경우에만 발생합니다.
를 사용하면 -t
파이프 sshd
가 사용되지 않습니다. 대신 원격 셸 및 해당 하위 항목(stdin, stdout, stderr)과의 모든 상호 작용은 한 쌍의 의사 터미널을 사용하여 수행됩니다.
의사 터미널 쌍의 경우 sshd
마스터와 상호 작용하기 위한 유사한 eof 처리가 없지만 적어도 일부 시스템은 의사 터미널의 슬레이브 측에 아직 열려 있는 프로세스가 있는지 알 수 있는 대체 방법을 제공합니다(아래 @JdeBP 주석 참조). ), sshd
사용하지 않으므로 원격 사용자의 로그인 셸을 실행하는 프로세스가 종료되기를 기다렸다가 종료합니다.
종료 시 pty 쌍의 마스터 측이 닫힙니다. 이는 pty가 파괴됨을 의미하므로 슬레이브 제어 프로세스는 SIGHUP(기본적으로 종료됨)을 수신하게 됩니다.
편집하다:최종 결과는 동일하지만 마지막 부분이 올바르지 않습니다. 바라보다@UNIX.root의 답변정확히 무슨 일이 일어났는지 정확하게 설명하세요.
답변2
(더 많은 정보를 포함하기 위해 댓글을 여기로 옮겼습니다.)
허용된 답변의 일부 SIGHUP
가 올바르지 않습니다.
종료 시 pty 쌍의 마스터 측이 닫힙니다. 이는 pty가 파괴됨을 의미하므로 슬레이브가 제어하는 프로세스는 SIGHUP을 수신하게 됩니다.
그렇지 않다. POSIX에 따르면 " 제어 터미널의 터미널 인터페이스가 모뎀 연결 끊김을 감지하면 SIGHUP
신호가 전송되어야 합니다. [...]프로세스를 제어하기 위해의 경우 ssh -t 'sleep 2 &'
tty의 연결이 끊어지고 SIGHUP
이미 종료되었기 때문에 제어 프로세스로 보낼 수 없는 것은 종료되는 제어 프로세스입니다. 실제로 sleep
살해당한 SIGHUP
이유는 언제였습니까?세션 리더 종료, "이 SIGHUP
신호는 모든 프로세스에 전송되어야 합니다.포그라운드 프로세스 그룹에서".
혼란스러운 부분은 그렇습니다 sleep 2 &
. 이것은 백그라운드에서 실행되는 명령이지만 그렇지 않습니다.백그라운드 프로세스 그룹. 백그라운드 프로세스 그룹 관련직업 통제기본적으로 비대화형 셸(예: ssh ... 'sleep 2 &'
)에서는 비활성화되어 있습니다. 실제로 sleep 2 &
달리는 중포그라운드 프로세스 그룹. 예를 들어:
$ ssh -t localhost 'sleep 2 & ps jt'
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
88819 88825 88825 88825 pts/36 88825 Ss+ 0 0:00 bash -c sleep 2 & ps jt
88825 88826 88825 88825 pts/36 88825 S+ 0 0:00 sleep 2
88825 88827 88825 88825 pts/36 88825 R+ 0 0:00 ps jt
보시다시피 모든 프로세스의 PGID(88825)는 bash 쉘의 PID와 동일하며, TPGID도 88825입니다. 즉, 백그라운드 프로세스 sleep 2 &
도 여기에 있습니다.포그라운드 프로세스 그룹.
비교를 위해 다음을 참조하세요.
$ pgrep -af sleep
$ ssh -t localhost 'set -m; sleep 123 & ps jt'
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
89002 89008 89008 89008 pts/3 89010 Ss 0 0:00 bash -c set -m; sleep 123 & ps jt
89008 89009 89009 89008 pts/3 89010 S 0 0:00 sleep 123
89008 89010 89010 89008 pts/3 89010 R+ 0 0:00 ps jt
Connection to localhost closed.
$ ps j 89009
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
1 89009 89009 89008 ? -1 S 0 0:00 sleep 123
$
set -m
작업 제어가 활성화되면( ) sleep 2 &
자체 프로세스 그룹(PGID 89009)에서 실행되고 있음 을 알 수 있습니다 .백그라운드 프로세스 그룹. 그리고 ssh
종료 후에도 sleep
계속 실행 중입니다.
(자세한 내용은 다음과 유사한 시나리오를 참조하세요.+ "ssh -f"가 작동하지 않을 것으로 예상됩니다.)
답변3
사용 wait
:
ssh user@example -t 'sleep 2 & wait'