ssh 종료 후 ssh 명령이 예기치 않게 다른 시스템에서 계속됨

ssh 종료 후 ssh 명령이 예기치 않게 다른 시스템에서 계속됨

다음 명령을 실행하고 다른 시스템에서 출력 파일을 모니터링하고 있습니다.

ssh $ip_address 'for n in 1 2 3 4 5; do sleep 10; echo $n >>/tmp/count; done'

^C로그인한 터미널을 사용하거나 그냥 종료하여 ssh 명령을 종료하면 원격 명령도 종료될 것으로 예상됩니다. 그러나 그런 일은 일어나지 않습니다. /tmp/count어쨌든 1-5의 모든 숫자를 가져오고 ps -ejH셸과 sleep해당 하위 프로세스가 계속 실행되는 것으로 표시됩니다.

이것이 예상되는 동작입니까? 어디에도 문서화되어 있나요? 비활성화할 수 있나요? 읽으면서 이 동작을 기본 동작으로 두는 대신 nohup을 사용하여 명시적으로 활성화해야 한다고 예상했습니다.

ssh 및 sshd에 대한 매뉴얼 페이지를 살펴봤지만 명확한 내용을 찾지 못했고 Google은 이 동작을 끄는 지침이 아니라 켜는 지침을 알려 주었습니다.

저는 두 시스템 모두에서 루트 로그인과 bash 쉘을 사용하여 Red Hat Enterprise Linux 6.2를 실행하고 있습니다.

답변1

우서의 대답터미널을 할당하라고 지시하지만 그 이유는 설명하지 않습니다. 그 이유는 ssh에만 국한된 것이 아니라 신호 생성 및 전파 문제입니다. 나는 당신을 초대합니다.다양한 신호가 전송되는 원인은 무엇입니까?배경에 대해 자세히 알아보세요.

원격 호스트에는 두 가지 관련 프로세스가 있습니다.

  • sshd원격 프로그램의 입력 및 출력을 로컬 터미널로 중계하는 ssh 데몬( )의 인스턴스입니다.
  • 루프 를 실행하는 쉘입니다 for.

쉘은 루프의 끝에 도달하거나 치명적인 오류가 발생하면 자연스럽게 죽을 수도 있고, 신호로 인해 죽을 수도 있습니다. 문제는 쉘이 신호를 수신하는 이유는 무엇입니까?

원격 셸이 파이프를 통해 연결된 경우 sshd(명령줄에서 명령을 지정할 때 발생) ssh, 종료됩니다.신호 파이프라인종료 되고 sshd쉘이 파이프에 쓰기를 시도하는 경우. 쉘이 파이프에 쓰지 않는 한 SIGPIPE를 수신하지 않습니다. 여기서 쉘은 표준 출력에 아무 것도 쓰지 않으므로 영원히 지속될 수 있습니다.

-t이 옵션을 ssh에 전달하여 원격 측에서 터미널을 에뮬레이트하고 이 터미널에서 지정된 명령을 실행하도록 지시 할 수 있습니다 . 그런 다음 SSH 클라이언트가 사라지면 sshd연결을 닫고 종료하여 터미널을 파괴합니다. 터미널 장치가 사라지면 그 안에서 실행 중인 모든 프로세스는한숨을 쉬다. 따라서 SSH 클라이언트를 종료하면( kill클라이언트가 실행 중인 터미널을 사용하거나 닫아서) 원격 셸은 SIGHUP 신호를 내보냅니다.

-t옵션이 전달되면 SSH도 릴레이합니다.지능을 신호하다. Ctrl+를 누르면 C원격 쉘이 SIGINT를 수신합니다.

답변2

명령을 사용하여 psuedo-tty를 할당해 보십시오 ssh.

ssh -t $ip_address 'for n in 1 2 3 4 5; do sleep 10; echo $n >>/tmp/count; done'

SSH 세션 연결을 끊으면 프로세스가 종료됩니다.

이는 의사 tty이므로 쉘 초기화 시 구성 파일의 소스 코드를 가져오지 못해 명령이 매우 노출된 환경에 남아 있을 수 있습니다. .ssh/environment환경 변수(예: PATH)를 정의하는 파일을 설정해야 할 수도 있습니다 . ~에서man 1 ssh

Additionally, ssh reads ~/.ssh/environment, and adds lines of the format 
“VARNAME=value” to the environment if the file exists and users are allowed
to change their environment.  For more information, see the 
PermitUserEnvironment option in sshd_config(5).

답변3

-tssh클라이언트가 종료되거나 종료될 때 원격 명령이 종료되도록 하는 옵션을 사용하는 대신 표준 입력을 닫을 때 ssh명명된 파이프를 사용하여 sshd"EOF를 SIGHUP"으로 변환할 수 있습니다(참조).버그 396 - pty가 할당되지 않으면 sshd가 고아 프로세스가 됩니다.).

# sample code in Bash
# press ctrl-d for EOF
ssh localhost '
TUBE=/tmp/myfifo.fifo
rm -f "$TUBE"
mkfifo "$TUBE"
#exec 3<>"$TUBE"

<"$TUBE" sleep 100 &  appPID=$!

# cf. "OpenSSH and non-blocking mode", 
# http://lists.mindrot.org/pipermail/openssh-unix-dev/2005-July/023090.html
#cat >"$TUBE"
#socat -u STDIN "PIPE:$TUBE"
dd of="$TUBE" bs=1 2>/dev/null
#while IFS="" read -r -n 1 char; do printf '%s' "$char"; done > "$TUBE"

#kill -HUP -$appPID 
kill $appPID

rm -f "$TUBE"
'

답변4

비활성화하려면(기본 동작으로 보임) 활성화해야 합니다.SSH는 살아있다클라이언트 또는 서버 측.

ssh-keep-alive-options에 대한 매뉴얼 페이지를 보면 기본적으로 비활성화되어 있음을 알 수 있습니다.

관련 정보