멈추고 싶을 때는 +를 tail -f
누르고 프롬프트로 돌아갑니다. 하지만 연결을 위해 ssh를 실행하면 +가 연결을 끊습니다. (국기의 의미에 대한 설명)CTRLCCTRLC여기)
ssh -t svf "cd ~/w/logs; tail -f some_file.log; exec $SHELL -l"
이것게시물에는 원격 셸이 종료되는 것을 방지하는 방법이 설명되어 있지 않습니다.ssh -t remotehost command args ...
tail -f
SSH 연결을 중단하지 않고 +stop 명령(이 경우)을 어떻게 사용할 수 있습니까 ?CTRLC
답변1
존재하다
ssh -t svf "cd ~/w/logs; tail -f some_file.log; exec $SHELL -l"
-t
로컬 tty 회선 규칙이 원시(패스스루) 모드로 설정되고 의사 tty가 원격 측에 생성됨을 나타냅니다.
의사 터미널은 기본 설정을 갖게 되며, 이는 대부분의 시스템에서 예를 들어 하나의 ^C
문자로 인해 SIGINT가 의사 터미널의 전경 프로세스 그룹으로 전송된다는 것을 의미합니다.
여기서는 ssh
명령을 사용할 때 를 sshd
실행합니다 login-shell-of-the-remote-user -c that-command
. 이는 비대화형 셸이므로 작업 제어를 수행하지 않습니다.
특히 쉘은 실행하는 모든 명령과 동일한 프로세스 그룹, 즉 터미널의 포그라운드 프로세스 그룹에서 실행됩니다.
그러나 쉘 $SHELL -l
( $SHELL
아마도 원하는 것이 아닐 수도 있는 로컬 시스템에서 확장됨)은 대화형 쉘이 될 것입니다(호출이 수행되지 않고 -c
stdin이 터미널 장치이므로). 따라서 다른 위치에 있게 됩니다. 프로세스 그룹 내 명령(파이프)을 실행하고 필요에 따라 이를 터미널의 포그라운드 프로세스로 만들지 여부를 지정하는 프로세스 그룹입니다.
여기에서는 SIGINT만 수신하도록 tail -f
하거나 최소한 셸이 아닌 종료하도록 하려면 원격 사용자의 로그인 셸에 따라 몇 가지 옵션이 있습니다.
원격 사용자의 로그인 쉘이 bash
또는 인 경우 yash
다음을 수행할 수 있습니다.
ssh -t svf 'set -m; cd ~/w/logs && tail -f some_file.log; exec "$SHELL" -l'
이 -m
옵션을 사용하면 작업 제어가 가능해집니다. 이는 쉘이 별도의 프로세스 그룹(대화형 쉘과 같은)에서 파이프를 실행하도록 지시하며( bash
및 yash
일반적으로 다른 모든 쉘의 경우는 아님) 전경에서 실행 중인 파이프의 프로세스 그룹이 파이프의 전경 프로세스 그룹이 됩니다. 터미널 장치(예: 켜지 SIGINT
거나 ^C
꺼짐 SIGTSTP
), 백그라운드에서 시작된 장치는 그렇지 않습니다(따라서 터미널에서 읽는 것이 금지됩니다(SIGTTIN 수신)).^Z
이렇게 하면 tail -f
포그라운드 프로세스 그룹이 될 자체 프로세스 그룹에서 실행됩니다. tail
실행하는 동안 Ctrl+C를 입력하면 SIGINT 만 tail
받게 됩니다.
쉘이 Bourne과 유사하다는 것을 알고 있다면 또 다른 옵션은 SIGINT에 대한 핸들러를 설정하는 것입니다.
ssh -t svf 'trap : INT; cd ~/w/logs && tail -f some_file.log; exec "$SHELL" -l'
:
여기서는 SIGINT를 수신할 때 명령을 실행(작업 없음) 하도록 셸을 구성합니다 . 하위 프로세스는 핸들러를 상속하지만 명령이 실행되면 핸들러가 기본값으로 재설정됩니다(프로세스 종료).
따라서 이제 실행 중에 CTRL-C를 누르면 tail
쉘과 테일 모두 tail
SIGINT를 수신하지만 tail만 종료되고 쉘은 계속 실행됩니다 "$SHELL" -l
.
원격 호스트(그리고 원격 셸이 Bourne 또는 csh와 유사함)에서 이를 알고 있거나 액세스할 수 있는 경우 bash
다음 을 수행할 수도 있습니다.yash
ssh -t svf 'cd ~/w/logs && bash -c "set -m; tail -f some_file.log"; exec "$SHELL" -l'
쉘을 명시적으로 호출 bash
하고 옵션을 켜서 자체 포그라운드 프로세스 그룹에서 시작하고 첫 번째 솔루션처럼 SIGINT만 수신하도록 합니다 -m
.tail
bash-4.3
이상을 사용하면 bash -c "set -m;
로 대체할 수 있습니다 bash -mc "
. 이는 인터프리터에 전달된 ( -m
and ) 옵션을 무시하는 이전 버전에서는 작동하지 않습니다 -i
( .bash
-c
답변2
CTRL+ 연결 끊김을 방지하려면 C대화형이어야 합니다.
이는 를 통해 달성됩니다 bash -i
. 그래서 나는 실행할 수 있습니다 :
ssh -t svf 'cd ~/w/logs; bash -i tail -f some_file.log; exec $SHELL -l'
하지만 이런 이유는저것질문. 이 문제를 해결하려면 해결 방법을 만들 수 있습니다. 명령을 실행하기 위해 원격 시스템에 스크립트를 생성합니다(-i
표지판 에 주의하세요 . 이건 중요하다.일반 로그인과 동일한 ENV가 필요한 경우 -l
플래그를 추가할 수도 있습니다 .
$ cat ~/cmd
#!/bin/bash -i
cmd="$*"
eval $cmd
그런 다음 명령을 다음과 같이 수정했습니다.
ssh -t svf 'cd ~/w/logs; ~/cmd tail -f some_file.log; exec $SHELL -l'
이제 나는 행복하며 CTRL+ Cwhen 을 실행할 수 있습니다 tail -f
. 상호 작용으로 인해 bash -i
SSH 연결이 중단되지 않고 exec $SHELL -l
단축키가 호출된 후 명령이 실행됩니다.
중요한 팁:로컬 대신 원격 측에서 $SHELL을 확장하려면 '대신 '을 사용해야 합니다. 감사합니다. Stéphane Chazelas