SSH 전달 신호 받기

SSH 전달 신호 받기

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을 누르세요.

긴 설명:

  1. 서버 또는 로컬을 변경하려면 stty옵션을 사용해야 합니다.intr문자 끊기서로 충돌을 피하기 위해. 위 명령에서 서버 중단 문자를 CTRL+N으로 변경했습니다. 로컬 중단 문자를 변경하고 변경 사항 없이 서버의 중단 문자를 유지할 수 있습니다.
  2. 출력에 중단 문자(다른 제어 문자와 함께)가 표시되지 않도록 하려면 사용하십시오 stty -echoctl.
  3. sshd가 호출하는 서버 bash에서 제어 문자가 켜져 있는지 확인해야 합니다. 이렇게 하지 않으면 로그아웃한 후 프로세스가 중단될 수 있습니다.stty isig
  4. 실제로 SIGINT빈 명령문을 사용하여 신호를 포착할 수 있습니다. trap '/bin/true' SIGINT트랩이 없으면 SIGINT 신호 뒤에 표준 출력이 나오지 않습니다.

답변2

모든 솔루션을 시도했는데 이것이 최고입니다.

ssh host "sleep 99 < <(cat; kill -INT 0)" <&1

https://stackoverflow.com/questions/3235180/starting-a-process-over-ssh-using-bash-and-then-killing-it-on-sigint/25882610#25882610

답변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

관련 정보