मुझे नहीं लगता कि आप इसके आसपास पहुँच सकते हैं।
के साथ -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
इनपुट पक्ष पर बहुत कुछ होगा ( ^C
चरित्र की तरह जो एक संकेत का कारण होगा, लेकिन अन्य संकेत भी, गूंज और विहित मोड लाइन संपादक में शामिल सभी हैंडलिंग )।
आप संभवतः एक पेंडो में stderr को पुनर्निर्देशित कर सकते हैं और एक दूसरे का उपयोग करके इसे पुनः प्राप्त कर सकते हैं ssh
:
ssh -tt host 'mkfifo fifo && cmd 2> fifo' &
ssh host 'cat fifo' >&2
लेकिन सबसे अच्छा आईएमओ -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 पर पाइप के पढ़ने के अंत के लिए) एक हैंग-HUP घटना के लिए इंतजार करना है। एक अनुरोधित मास्क के रूप में POLLHUP को अनदेखा किया जाता है। POLLHUP केवल लौटी हुई घटना के रूप में अर्थपूर्ण है (यह बताने के लिए कि लेखन समाप्ति बंद हो गई है)।
हमें इवेंट मास्क के लिए एक गैर-शून्य मान देना होगा। यदि हम उपयोग करते हैं 0
, perl
तो कॉल भी नहीं करता है poll
। इसलिए यहाँ हम POLLIN का उपयोग करते हैं।
लिनक्स पर, आप जो भी अनुरोध करते हैं, अगर पाइप टूट जाता है, तो पोल () पोलरआर वापस कर देता है।
सोलारिस और फ्रीबीएसडी पर, जहां पाइप द्विदिश हैं, जब पाइप का रीडिंग एंड (जो वहां राइटिंग एंड भी है) बंद है, तो यह POLLHUP (और FreeBSD पर POLLIN) के साथ लौटता है, जहां आपको LLIN का अनुरोध करना होता है या फिर $p->poll()
नहीं वापसी)।
मैं यह नहीं कह सकता कि उन तीन ऑपरेटिंग सिस्टम के बाहर यह कितना पोर्टेबल है।
parallel --tag -j1 'ssh -tt localhost perl/catch_wrap perl/catch_all_signals & sleep 1; killall -{} ssh' ::: {1..31}
लेकिन '-tt' को हटा दें और फिर यह काम नहीं करता है।