आगे के संकेतों के लिए ssh प्राप्त करें


22

मैं ssh के माध्यम से संकेत (SIGINT सबसे महत्वपूर्ण है) भेजने में सक्षम होना चाहता हूं।

यह आदेश:

ssh server "sleep 1000;echo f" > foo

सर्वर पर सोना शुरू कर देगा और 1000 सेकंड के बाद यह मेरे स्थानीय मशीन पर फ़ाइल foo में 'f \ n' डाल देगा। अगर मैं CTRL-C दबाता हूं (यानी sshINT को ssh में भेजें) तो यह ssh को मार देगा, लेकिन यह रिमोट सर्वर पर नींद को नहीं मारेगा। मैं चाहता हूं कि यह रिमोट सर्वर पर नींद को मार दे।

इसलिए मैंने कोशिश की:

ssh server -t "sleep 1000;echo f" > foo

लेकिन अगर स्टडिन एक टर्मिनल नहीं है तो मुझे यह त्रुटि मिलती है:

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' होता है, जो मेरी स्थिति में विनाशकारी होता है (जैसा कि मेरा आउटपुट बाइनरी डेटा है)।

ऊपर मैं "स्लीप 1000; इको एफ" का उपयोग करता हूं, लेकिन वास्तव में उपयोगकर्ता द्वारा आपूर्ति की जाती है, इस प्रकार इसमें कुछ भी हो सकता है। हालांकि, अगर हम इसे "स्लीप 1000; इको एफ" के लिए काम कर सकते हैं, तो हम संभवतः इसे सभी यथार्थवादी स्थितियों के लिए काम कर सकते हैं।

मैं वास्तव में दूसरे छोर पर एक छद्म टर्मिनल प्राप्त करने के बारे में परवाह नहीं करता हूं, लेकिन मैं अपने SIGINT को आगे बढ़ाने के लिए ssh प्राप्त करने का कोई अन्य तरीका खोजने में असमर्थ रहा हूं।

क्या कोई और तरीका है?

संपादित करें:

उपयोगकर्ता आदेश दे सकता है कि स्टड से द्विआधारी डेटा पढ़ें, जैसे:

seq 1000 | gzip | ssh server "zcat|bzip2; sleep 1000" | bzcat > foo

उपयोगकर्ता ऐसे कमांड दे सकते हैं जो सीपीयू के गहन हों, जैसे:

ssh server "timeout 1000 burnP6"

EDIT2:

जो संस्करण मेरे लिए काम करता है वह है:

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को उदाहरणों के रूप में दिखाए जाने की तुलना में अधिक जटिल होना चाहिए, क्योंकि आप एक सरल पुनर्व्यवस्थापन के साथ इच्छित व्यवहार प्राप्त कर सकते हैं: sleep 1000 && ssh server "echo f" > foo(यह होना चाहिए &&, नहीं ;, ताकि हत्या कमांड को चलने से sleepरोक sshदे।) यदि मैं सही है, कृपया अपने उदाहरणों को अपने वास्तविक उपयोग के अधिक प्रतिनिधि बनाएं, इसलिए बेहतर उत्तर दिया जा सकता है।
वॉरेन यंग

सही: नींद और प्रतिध्वनि वास्तव में उपयोगकर्ता द्वारा आपूर्ति की गई स्क्रिप्ट हैं और शाब्दिक रूप से नींद और प्रतिध्वनि नहीं हैं। इसलिए हम नहीं जानते कि वे क्या करते हैं और उन्हें सबसे बुरा मानना ​​चाहिए।
ओले तांगे

Sooo ... आप एक बेहतर उदाहरण कमांड के साथ आने वाले हैं, है ना? जहां एक साधारण व्यवस्था समस्या को ठीक नहीं करती है? आप एक अच्छा सवाल पूछते हैं, और मैं इसका उत्तर देखना चाहता हूं, लेकिन आपको उत्तर मिलने की संभावना कम है अगर "ऐसा नहीं करते हैं, तो" एक उचित उत्तर है।
वॉरेन यंग

ओह ... वैसे मत करो;)
टिम

जैसा कि इस प्रश्न में स्पष्ट किया गया है: "" "उपरोक्त में मैं" स्लीप 1000; इको एफ "का उपयोग करता हूं, लेकिन वास्तव में उपयोगकर्ता द्वारा आपूर्ति की जाती है, इस प्रकार इसमें कुछ भी हो सकता है" "
ओले तांगे

जवाबों:


10

संक्षिप्त जवाब:

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 द्वारा आहूत सर्वर बैश पर स्विच किए गए हैं। यदि आप नहीं करते हैं तो आप लॉगआउट होने के बाद भी प्रक्रियाओं को खत्म कर सकते हैं।stty isig
  4. आप वास्तव में खाली बयान के साथ SIGINTसंकेत पकड़ते हैं trap '/bin/true' SIGINT। जाल के बिना आपके अंत में SIGINT सिग्नल के बाद आपके पास कोई स्टडआउट नहीं होगा।

ऐसा लगता है कि द्विआधारी इनपुट के साथ अच्छी तरह से सौदा नहीं है: seq 1000 | gzip | ssh -t -t server "stty isig intr ^ N -echoctl; जाल '/ बिन / सच' SIGINT; नींद 1; zcat | bzip2" bzcat> foo;
ओले तांगे

यदि आप किसी अन्य चीज़ के लिए ssh के लिए मानक इनपुट सेट करते हैं तो आप कंसोल द्वारा बाधित नहीं कर सकते। इस स्थिति में आपको स्टडिन स्ट्रीम द्वारा बाधित होना चाहिए।
डिजिटल_इनफिनिटी

मैंने पाया कि यह seq 1000 | gzip | ssh -tt dell-test "zcat|bzip2" | bzcat > fooभी काम नहीं करता है। यह कमांड काम करने के लिए हमें निकालने की आवश्यकता है -tt। इसलिए छद्म टर्मिनल आवंटन शायद
स्टड

मैंने uuencode की कोशिश की। इस संस्करण में यह काम नहीं करता है: बिल्ली foo.gz | perl -ne 'प्रिंट पैक ("यू", $ _)' | ssh -t -t server 'perl -ne "प्रिंट अनपैक (\" u \ ", \ $ _)" | zcat | gzip | perl -ne "प्रिंट पैक (\" u \ ", \ $ _)" '| perl -ne 'प्रिंट अनपैक ("यू", $ _)'> foo2.gz
ओले

1
मैं इस किया है: (sleep 1; seq 1000 ) | gzip | uuencode bin | ssh -tt dell-test "stty isig intr ^N -echoctl -echo ; trap '/bin/true' SIGINT; sleep 1; uudecode -o /dev/stdout | zcat |bzip2 | uuencode bin2 " | uudecode -o /dev/stdout | bzcat >foo। हालांकि इंटरप्ट कैरेक्टर काम नहीं करता है - स्ट्रेन बिजी होने पर हमें इंटरप्ट कैरेक्टर के लिए कुछ ट्रांसमिशन विधि की जरूरत होती है
डिजिटल_इनफिनिटी

3

मैंने सभी समाधानों की कोशिश की और यह सबसे अच्छा था:

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

/programming/3235180/starting-a-process-over-ssh-using-bash-and-then-killing-it-on-sigint/25882610#25882610


sleepकनेक्शन खो जाने की स्थिति में यह प्रक्रिया बंद नहीं करता है।
blueyed

जब कनेक्शन खो जाता है तो स्टडिन को बिल्ली को अनब्लॉक करना टूट जाता है जो प्रक्रिया समूह को मार देगा। क्या आपके कार्य के लिए इंटेरप्ट सिग्नल काफी अच्छा है या नहीं यह एक अलग प्रश्न है।
एरिक वुडरफ

यह sleep, के लिए पर्याप्त होना चाहिए यह नहीं होना चाहिए? मैंने कुछ के date >> /tmp/killedबाद जोड़ा है cat, लेकिन यह ट्रिगर नहीं किया गया था। क्या इसमें कुछ समयावधि शामिल है? मैं सामान्य रूप से Zsh का उपयोग कर रहा हूं, लेकिन इसे रिमोट लॉगिन शेल के रूप में बैश के साथ भी परीक्षण किया है।
blueyed

मुझे लगता है कि आप कनेक्शन टाइमआउट की दया पर हैं।
एरिक वुड्रूफ़

क्या इसे नियंत्रित करने के लिए सेटिंग्स हैं? क्लाइंट पक्ष के -o ServerAliveInterval=3 -o ServerAliveCountMax=2लिए यह जल्दी से पता लगाने की अनुमति देता है, लेकिन क्या सर्वर साइड के लिए कुछ है?
blueyed

2

मुझे लगता है कि आप उस प्रक्रिया की पीआईडी ​​पा सकते हैं जो आप सर्वर पर चला रहे हैं और दूसरे sshकमांड का उपयोग करके सिग्नल भेजते हैं (जैसे:) ssh server "kill -2 PID"

मैं एक अलग मशीन पर चलने वाले अनुप्रयोगों के लिए पुन: कॉन्फ़िगर करने के संकेत भेजने के लिए इस विधि का उपयोग करता हूं (मेरे अनुप्रयोग SIGUSR1 को पकड़ते हैं और एक विन्यास को पढ़ते हैं)। मेरे मामले में पीआईडी ​​ढूंढना आसान है, क्योंकि मेरे पास अद्वितीय प्रक्रिया नाम हैं और मैं पीआईडी ​​को एक psअनुरोध भेजकर पा सकता हूं ssh


मुझे रिमोट पर चलाए जा रहे कार्यक्रम के पीआईडी ​​को खोजने का बुलेट प्रूफ तरीका नहीं दिख रहा है। याद रखें कि यह उपयोगकर्ता द्वारा दिया गया है। यह हो सकता है: ssh सर्वर 'निष्पादित $ (echo fyrrc 1000 | / usr / games / rot13)'
Ole Tange

1

समाधान http://www.gnu.org/software/parallel/parallel_design.html#Remote-Ctrl-C-and-standard-error-stderr में विकसित हुआ

$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)

0

----- कमांड.श

#! /bin/sh
trap 'trap - EXIT; kill 0; exit' EXIT
(sleep 1000;echo f) &
read ans

----- स्थानीय टर्मिनल पर

sleep 864000 | ssh -T server command.sh > foo

नमस्ते! मुझे लगता है कि आप अपने उत्तर को और अधिक उपयोगी बना सकते हैं, यह समझाकर कि आप कितना प्रासंगिक हैं, यह कैसे काम करता है। नई जानकारी सम्मिलित करने के लिए इसे संपादित करने में संकोच न करें।
धग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.