종료 시 원격 터미널이 정지되는 이유는 무엇입니까?

종료 시 원격 터미널이 정지되는 이유는 무엇입니까?

나는 다음과 같이 작동하는 원격 tty 도구("rt"라고 함)를 작성했습니다.

[rt client(rtc)] <--->  [rt gateway(rtg)] <---> [rt server(rts)]

rtsNAT 방화벽 뒤의 호스트는 어디에 실행되고 rt/etc/rc.local연결됩니다 rtg. rts에 연결하고 싶을 때 rtc컴퓨터에서 rt를 실행하면 에 연결되고 rtg에 요청이 전송됩니다 rts. 프로그램 은 TTY에서 시작 rt되어 ./usr/bin/loginrtcrts

내 문제는 원격 터미널에서 일부 명령을 실행한 다음 exitbash를 종료하도록 입력하면 로컬 터미널 프롬프트로 돌아가고 싶지만 거의 항상 멈추고 빈 화면이 표시된다는 것입니다.와는 별개로bash 명령만 실행하고 원격 세션에서 외부 프로그램을 실행하지 않는 경우.

편집하다:

외부 프로그램이 무엇인지 정확히 정의하는 것은 다소 어렵습니다. 프로그램에 "데몬"이 없으면 "내부"로 간주된다는 느낌이 듭니다. 즉, 등을 실행하면 ls괜찮지 cpvi명령 &줄 끝에서 을 사용하여 서비스 프로그램을 실행하면 rt종료 시 중단됩니다.


몇 가지 조사를 해봤지만 안타깝게도 문제를 한 문장으로 설명하기가 어렵습니다. 내가 찾을 수 있는 가장 관련성이 높은 리소스는 다음과 같습니다.

터미널 에뮬레이터가 종료되면 쉘도 종료되는 이유는 무엇입니까?

어딘가에 보내면 도움이 될 것 같은데 SIGHUP어떻게요? 어떤 프로그램이 송신자이고 어떤 프로그램이 수신자입니까?

답변1

설명하는 동작은 TTY(즉, 원격 터미널의 출력)에서 읽고 EOF를 얻을 때까지 계속 읽고(필요한 경우 대기하는) 컨트롤러 소프트웨어의 일반적인 동작입니다. 그러나 pseudo-tty는 파이프와 같습니다. 읽기 프로세스는 쓰기 위해 연 모든 프로세스가 닫힐 때까지 EOF를 얻지 못합니다. (프로세스가 종료되면 열려 있는 모든 파일이 닫힙니다.)

그러나 표준 출력 및 표준 오류를 리디렉션하지 않는 한 비동기 프로세스는 stdout 및 stderr로 쓰기 위해 tty를 열어 둡니다. nohup주요 기능은 중단(HUP) 신호를 무시하는 것이지만 보조 기능은 stdout 및 stderr이 tty를 가리키지 않도록 하는 것입니다 .  >출력 스트림을 리디렉션하기 위해 및(또는 그 변형)을 사용하는 경우에는 2>그대로 nohup두어도 됩니다. 그러나 출력을 리디렉션하지 않는 nohup경우  nohup.out.

긴 이야기 짧게 stdout 및 stderr을 리디렉션하지 않고(안전을 위해 stdin도 리디렉션하지 않고) 비동기 명령을 실행하는 경우 셸을 종료하면 rt모든 백그라운드 프로세스가 참조하는 파일 설명자를 닫을 때까지 프로그램이 종료되지 않습니다. 디. 사실상 이는 백그라운드 프로세스가 종료될 때까지 기다린다는 의미입니다.

제가 보기에 "간단하고 명확한" 해결책은 하위 프로세스가 종료될 때 종료되도록 프로그램을 수정하는 것입니다. 사용자(즉, 귀하)가 로그인할 때 얻는 대화형 셸 프로세스 똑같은 과정이에요당신이 시작한 것처럼 /usr/bin/login. 나는 당신이 fork()and exec() (또는 그것의 변형)을 사용하여 이 작업을 수행하기를 원합니다. 따라서 PID를 추적하고 호출 wait() (또는 그 변형)하면 됩니다.

노트:

  • 의사 TTY에서 동시에 읽는 동안 셸이 종료될 때까지 기다리려면 여러 프로세스 또는 최소한 여러 스레드를 사용해야 합니다.
  • nc( netcat), , 등 이미 이러한 상황을 처리하는 프로그램이 많이 있으며 sshd그 중 일부는 오픈 소스라고 확신합니다. 이를 확인하여 몇 가지 아이디어(및 일부 코드)를 얻을 수 있습니다.
  • wait()고려해야 할 기능 중 하나는 rtTTY 출력 버퍼에서 예외를 처리하기 위해 종료하기 전에 반환 후 몇 초 동안 대기하는 것입니다. 위에서 언급한 일부 프로그램이 이 작업을 수행할 수 있다는 것을 알게 될 것입니다.

관련 정보