나는 당신이 그 문제를 해결할 수 있다고 생각하지 않습니다.
함께 -tt, sshd스폰 의사 단말 및 슬레이브 부분을 원격 명령을 실행 쉘의 표준 입력, 표준 출력과 표준 에러를 만든다.
sshd(단일) fd에서 의사 터미널의 마스터 부분으로 들어오는 것을 읽고 (단일 채널을 통해) ssh클라이언트 에게 보냅니다 . 이 없으면 stderr에 대한 두 번째 채널이 없습니다 -t.
또한 의사 터미널의 터미널 라인 규칙은 출력을 변경할 수 있으며 기본적으로 출력을 변경할 수 있습니다. 예를 들어 LF는 로컬 터미널이 아닌 CRLF로 변환되므로 출력 사후 처리를 비활성화 할 수 있습니다.
$ ssh localhost 'echo x' | hd
00000000 78 0a |x.|
00000002
$ ssh -t localhost 'echo x' | hd
00000000 78 0d 0a |x..|
00000003
$ ssh -t localhost 'stty -opost; echo x' | hd
00000000 78 0a |x.|
00000002
^CSIGINT를 유발하는 문자뿐만 아니라 다른 신호, 에코 및 표준 모드 라인 편집기 와 관련된 모든 처리와 같이 입력 측에서 훨씬 더 많은 일이 발생합니다 .
stderr을 fifo로 리디렉션하고 초를 사용하여 검색 할 수 있습니다 ssh.
ssh -tt host 'mkfifo fifo && cmd 2> fifo' &
ssh host 'cat fifo' >&2
그러나 가장 좋은 IMO는 -t완전히 사용하지 않는 것 입니다. 그것은 실제로 실제 터미널에서 대화식으로 사용하기위한 것입니다.
^ C의 전송에 의존하여 원격으로 연결이 종료 poll()되도록하는 대신, ssh종료되거나 닫힌 연결 을 감지 하는 래퍼를 사용할 수 있습니다 .
어쩌면 (간단히, 약간의 오류 검사를 추가하고 싶을 것입니다) :
LC_HUP_DETECTOR='
use IO::Poll;
$SIG{CHLD} = sub {$done = 1};
$p = IO::Poll->new;
$p->mask(STDOUT, POLLIN);
$pid=fork; unless($pid) {setpgrp; exec @ARGV; die "exec: $!\n"}
$p->poll;
kill SIGHUP, -$pid unless $done;
wait; exit ($?&127 ? 128+($?&127) : 1+$?>>8)
' ssh host 'perl -e "$LC_HUP_DETECTOR" some cmd'
$p->mask(STDOUT, POLLIN)위 의 내용은 어리석은 것처럼 보이지만 행 아웃 이벤트 (stdout에서 파이프의 읽기 끝이 닫힐 때까지)를 기다리는 것이 좋습니다. 요청 된 마스크 인 POLLHUP 은 무시됩니다. POLLHUP은 반환 이벤트로만 의미가 있습니다 ( 쓰기 끝이 닫 혔음을 나타냅니다 ).
이벤트 마스크에 0이 아닌 값을 제공해야합니다. 우리가 사용하는 경우 0, perl전화도하지 않습니다 poll. 여기서는 POLLIN을 사용합니다.
Linux에서 요청한 내용에 관계없이 파이프가 손상되면 poll ()은 POLLERR을 반환합니다.
파이프의 읽기 끝 (또한 쓰기 끝이) 폐쇄 파이프 양방향 솔라리스와 FreeBSD,에, 당신이 POLLIN을 요청해야 FreeBSD의에 POLLHUP (그리고 POLLIN로 반환 그렇지 않으면 $p->poll()하지 않습니다 반환).
이 세 가지 운영 체제 외부에서 얼마나 이식성이 좋은지 말할 수 없습니다.
parallel --tag -j1 'ssh -tt localhost perl/catch_wrap perl/catch_all_signals & sleep 1; killall -{} ssh' ::: {1..31}하지만 '-tt'를 제거하면 작동하지 않습니다.