SSH를 통해 신호를 보낼 수 있기를 원합니다(SIGINT가 가장 중요함).
이 명령은 다음과 같습니다.
ssh server "sleep 1000;echo f" > foo
서버에서 잠자기 시작하고 1000초 후에 내 로컬 컴퓨터의 foo 파일에 "f\n"이 저장됩니다. CTRL-C를 누르면(즉, SIGINT를 ssh로 전송) ssh는 종료되지만 원격 서버에서는 절전 모드가 종료되지 않습니다. 원격 서버에서 절전 모드를 종료하고 싶습니다.
그래서 나는 다음을 시도한다:
ssh server -t "sleep 1000;echo f" > foo
그러나 stdin이 터미널이 아닌 경우 다음 오류가 발생합니다.
Pseudo-terminal will not be allocated because stdin is not a terminal.
그런 다음 SIGINT는 여전히 전달되지 않습니다.
그래서 나는 다음을 시도한다:
ssh server -t -t "sleep 1000;echo f" > output
그러나 foo의 출력은 "f\n"이 아니라 "f\r\n"입니다. 이는 제 경우에는 재앙입니다(내 출력은 이진 데이터이기 때문입니다).
위에서는 "sleep 1000;echo f"를 사용하고 있지만 실제로는 사용자가 제공한 것이므로 무엇이든 포함할 수 있습니다. 그러나 "sleep 1000;echo f"에 대해 작동하게 만들 수 있다면 아마도 모든 실제 상황에서 작동하게 만들 수 있을 것입니다.
나는 다른 쪽 끝에 의사 터미널을 얻는 것에 대해 별로 관심이 없지만 ssh가 내 SIGINT를 전달하도록 하는 다른 방법을 찾지 못했습니다.
다른 방법이 있나요?
편집하다:
사용자는 stdin에서 바이너리 데이터를 읽는 명령을 실행할 수 있습니다. 예를 들면 다음과 같습니다.
seq 1000 | gzip | ssh server "zcat|bzip2; sleep 1000" | bzcat > foo
사용자는 다음과 같이 CPU를 많이 사용하는 명령을 실행할 수 있습니다.
ssh server "timeout 1000 burnP6"
편집 2:
나에게 맞는 버전은 다음과 같습니다.
your_preprocessing |
uuencode a | ssh -tt -oLogLevel=quiet server "stty isig -echoctl -echo ; uudecode -o - |
your_command |
uuencode a" | uudecode -o - |
your_postprocessing
나에게 올바른 방향을 알려준 digital_infinity에게 감사드립니다.
답변1
짧은 답변:
ssh -t fs "stty isig intr ^N -echoctl ; trap '/bin/true' SIGINT; sleep 1000; echo f" > foo
프로그램을 중지하려면 Ctrl+N을 누르세요.
긴 설명:
- 서버 또는 로컬을 변경하려면
stty
옵션을 사용해야 합니다.intr
문자 끊기서로 충돌을 피하기 위해. 위 명령에서 서버 중단 문자를 CTRL+N으로 변경했습니다. 로컬 중단 문자를 변경하고 변경 사항 없이 서버의 중단 문자를 유지할 수 있습니다. - 출력에 중단 문자(다른 제어 문자와 함께)가 표시되지 않도록 하려면 사용하십시오
stty -echoctl
. - sshd가 호출하는 서버 bash에서 제어 문자가 켜져 있는지 확인해야 합니다. 이렇게 하지 않으면 로그아웃한 후 프로세스가 중단될 수 있습니다.
stty isig
- 실제로
SIGINT
빈 명령문을 사용하여 신호를 포착할 수 있습니다.trap '/bin/true' SIGINT
트랩이 없으면 SIGINT 신호 뒤에 표준 출력이 나오지 않습니다.
답변2
모든 솔루션을 시도했는데 이것이 최고입니다.
ssh host "sleep 99 < <(cat; kill -INT 0)" <&1
답변3
솔루션은 다음과 같이 발전했습니다.https://www.gnu.org/software/parallel/parallel_design.html#The-remote-system-wrapper
$SIG{CHLD} = sub { $done = 1; };
$pid = fork;
unless($pid) {
# Make own process group to be able to kill HUP it later
setpgrp;
exec $ENV{SHELL}, "-c", ($bashfunc."@ARGV");
die "exec: $!\n";
}
do {
# Parent is not init (ppid=1), so sshd is alive
# Exponential sleep up to 1 sec
$s = $s < 1 ? 0.001 + $s * 1.03 : $s;
select(undef, undef, undef, $s);
} until ($done || getppid == 1);
# Kill HUP the process group if job not done
kill(SIGHUP, -${pid}) unless $done;
wait;
exit ($?&127 ? 128+($?&127) : 1+$?>>8)
답변4
----- 명령.sh
#! /bin/sh
trap 'trap - EXIT; kill 0; exit' EXIT
(sleep 1000;echo f) &
read ans
----- 로컬 터미널에서
sleep 864000 | ssh -T server command.sh > foo