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