ฉันไม่คิดว่าคุณจะไปไหนมาไหนได้
ด้วย-tt
, sshd
spawns หลอกขั้วและทำให้ส่วนทาส stdin, stdout และ stderr ของเปลือกที่รันคำสั่งระยะไกล
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
สิ่งต่าง ๆ อีกมากมายที่จะเกิดขึ้นในด้านอินพุต (เช่น^C
ตัวละครที่จะทำให้เกิด SIGINT แต่รวมถึงสัญญาณอื่น ๆ เสียงสะท้อนและการจัดการทั้งหมดที่เกี่ยวข้องในตัวแก้ไขบรรทัดโหมด canonical )
คุณอาจเปลี่ยนเส้นทาง stderr ไปยัง fifo และดึงมันกลับมาโดยใช้วินาทีssh
:
ssh -tt host 'mkfifo fifo && cmd 2> fifo' &
ssh host 'cat fifo' >&2
แต่ IMO ที่ดีที่สุดคือหลีกเลี่ยงการใช้งานโดย-t
สิ้นเชิง นั่นมีไว้สำหรับการใช้งานแบบโต้ตอบจากเทอร์มินัลจริงเท่านั้น
แทนที่จะอาศัยการส่งสัญญาณของ ^ C เพื่อให้การเชื่อมต่อสิ้นสุดระยะไกลถูกปิดคุณสามารถใช้ wrapper ที่ทำหน้าที่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)
ข้างต้นอาจจะดูโง่ แต่ความคิดที่จะรอให้เหตุการณ์แขวน Hup (สำหรับส่วนการอ่านของท่อ stdout ที่จะปิด) POLLHUP ในฐานะมาสก์ที่ร้องขอจะถูกละเว้น POLLHUP เป็นเพียงความหมายเต็มว่าเป็นเหตุการณ์ที่ส่งคืน (เพื่อบอกว่าปลายการเขียนถูกปิดแล้ว)
เราต้องให้ค่าที่ไม่เป็นศูนย์สำหรับมาสก์ของเหตุการณ์ ถ้าเราใช้0
, ไม่ได้เรียกperl
poll
ดังนั้นที่นี่เราใช้ POLLIN
บน Linux ไม่ว่าคุณต้องการอะไรหากไพพ์เสียโพล () จะส่งคืน POLLERR
บน Solaris และ FreeBSD ที่ท่อเป็นแบบสองทิศทางเมื่อปิดจุดอ่านของท่อ (ซึ่งเป็นจุดสิ้นสุดการเขียน) ก็จะปิดลงโดยส่งคืนด้วย POLLHUP (และ POLLIN บน FreeBSD ซึ่งคุณต้องร้องขอ POLLIN $p->poll()
ไม่เช่นนั้น กลับ)
ฉันไม่สามารถพูดได้ว่าอุปกรณ์พกพานั้นอยู่นอกระบบปฏิบัติการทั้งสามนี้ได้อย่างไร
parallel --tag -j1 'ssh -tt localhost perl/catch_wrap perl/catch_all_signals & sleep 1; killall -{} ssh' ::: {1..31}
แต่ลบ '-tt' แล้วมันไม่ทำงาน