ssh कमांड अनपेक्षित रूप से ssh समाप्त होने के बाद अन्य सिस्टम पर जारी रहती है


11

मैं नीचे कमांड चला रहा हूं, और अन्य सिस्टम पर आउटपुट फाइल की निगरानी कर रहा हूं:

ssh $ip_address 'for n in 1 2 3 4 5; do sleep 10; echo $n >>/tmp/count; done'

अगर मैं ssh कमांड का उपयोग करके ^Cया सिर्फ उस टर्मिनल को मार रहा हूं, जिस पर मैं लॉग इन हूं, तो मैं रिमोट कमांड को समाप्त करने की उम्मीद करूंगा। हालांकि, ऐसा नहीं होता है: /tmp/countसभी नंबर 1-5 की परवाह किए बिना प्राप्त करता है, और ps -ejHशेल दिखाता है और इसका sleepबच्चा चलता रहता है।

क्या यह अपेक्षित व्यवहार है, और क्या यह कहीं भी प्रलेखित है? क्या मैं इसे निष्क्रिय कर सकता हूं? चारों ओर पढ़ने से, मुझे उम्मीद है कि इस प्रकार के व्यवहार को स्पष्ट रूप से सक्षम करना होगा, न कि डिफ़ॉल्ट के लिए।

मैंने ssh और sshd के लिए मैन पेजों पर एक नज़र डाली है, लेकिन स्पष्ट कुछ भी नहीं देखा है, और Google मुझे इस व्यवहार को चालू करने के निर्देशों पर इंगित करता है, इसे बंद करने के लिए नहीं।

मैं Red Hat Enterprise Linux 6.2 चला रहा हूं, दोनों सिस्टम पर रूट लॉगिन और बैश शेल के साथ।

जवाबों:


11

uther का जवाब आपको एक टर्मिनल आवंटित करने के लिए कहता है, लेकिन इसकी व्याख्या क्यों नहीं करता है। कारण ssh के लिए विशिष्ट नहीं है, यह सिग्नल जनरेशन और प्रचार का विषय है। मैं आपको पढ़ने के लिए आमंत्रित करता हूं कि विभिन्न संकेतों को भेजने का क्या कारण है? अधिक पृष्ठभूमि के लिए।

दूरस्थ होस्ट पर, दो प्रासंगिक प्रक्रियाएँ हैं:

  • ssh डेमॉन ( sshd) का एक उदाहरण , जो रिमोट प्रोग्राम के इनपुट और आउटपुट को स्थानीय टर्मिनल पर रिले कर रहा है;
  • एक शेल, जो उस forलूप को चला रहा है ।

शेल या तो स्वाभाविक रूप से मर सकता है जब यह लूप के अंत तक पहुंचता है या एक घातक त्रुटि का अनुभव करता है, या एक संकेत के लिए। सवाल यह है कि शेल को सिग्नल क्यों मिलेगा?

यदि रिमोट शेल sshdओवर पाइप्स से जुड़ा है ssh, तो कमांड लाइन पर कमांड निर्दिष्ट करने पर क्या होता है , अगर बाहर निकलता है तो यह एक SIGPIPE से मर जाएगा sshdऔर शेल पाइप पर लिखने की कोशिश करता है। जब तक शेल पाइप से नहीं लिख रहा है, तब तक उसे SIGPIPE प्राप्त नहीं होगा। यहां, शेल कभी भी अपने मानक आउटपुट के लिए कुछ भी नहीं लिख रहा है, इसलिए यह हमेशा के लिए रह सकता है।

आप -tssh के विकल्प को पास कर सकते हैं , यह बताने के लिए कि रिमोट पर टर्मिनल का अनुकरण करें और इस टर्मिनल में निर्दिष्ट कमांड को चलाएं। फिर, यदि SSH क्लाइंट गायब हो जाता है, sshdतो कनेक्शन को बंद कर देता है और टर्मिनल को नष्ट कर देता है। जब टर्मिनल डिवाइस चला जाता है, तो इसमें चलने वाली कोई भी प्रक्रिया एक SIGHUP प्राप्त करती है । इसलिए यदि आप SSH क्लाइंट (क्लाइंट के साथ killचल रहे टर्मिनल को बंद करके या बंद करके) को मारते हैं, तो रिमोट शेल SUPUPped है।

यदि आप -tविकल्प पास करते हैं , तो SSH SIGINT से भी संबंधित है । यदि आप Ctrl+ दबाते हैं C, तो दूरस्थ शेल एक SIGINT प्राप्त करता है।


-ttइसके बजाय का उपयोग करें -tअगर ssh ही एक tty आवंटित नहीं है। यदि ssh जैसे विकल्पों के माध्यम से मंगलाचरण के बाद तुरंत backgrounded हो जाता है SSH एक आवंटित tty नहीं मिलेगा -fया -n
मिरोन वी

3

अपने sshआदेश के साथ एक psuedo-tty आवंटित करने का प्रयास करें ।

ssh -t $ip_address 'for n in 1 2 3 4 5; do sleep 10; echo $n >>/tmp/count; done'

जब आप ssh सत्र को डिस्कनेक्ट करते हैं, तो प्रक्रिया समाप्त हो जानी चाहिए।

चूँकि यह एक छद्म tty है, इसलिए आपकी शेल आरंभीकरण संभवतया स्रोत कॉन्फ़िगरेशन फ़ाइलों में नहीं जा रहा है, जो आपके कमांड को बहुत नंगे वातावरण के साथ छोड़ रहा है। आपको ऐसी .ssh/environmentफ़ाइल सेट करने की आवश्यकता हो सकती है जो PATH जैसे पर्यावरण चर को परिभाषित करती है। सेman 1 ssh

Additionally, ssh reads ~/.ssh/environment, and adds lines of the format 
“VARNAME=value” to the environment if the file exists and users are allowed
to change their environment.  For more information, see the 
PermitUserEnvironment option in sshd_config(5).

2

जब ग्राहक बाहर निकलता है या (मारा जाता है), तो रिमोट कमांड बनाने के -tलिए विकल्प का उपयोग करने के विकल्प के रूप में , "EOF को SIGHUP" में परिवर्तित करने के लिए एक नामित पाइप का उपयोग किया जा सकता है जब स्टड बंद किया जा रहा है ( बग 396 देखें - sshd) अनाथ प्रक्रियाओं जब कोई pty आवंटित )।sshsshsshd

# sample code in Bash
# press ctrl-d for EOF
ssh localhost '
TUBE=/tmp/myfifo.fifo
rm -f "$TUBE"
mkfifo "$TUBE"
#exec 3<>"$TUBE"

<"$TUBE" sleep 100 &  appPID=$!

# cf. "OpenSSH and non-blocking mode", 
# http://lists.mindrot.org/pipermail/openssh-unix-dev/2005-July/023090.html
#cat >"$TUBE"
#socat -u STDIN "PIPE:$TUBE"
dd of="$TUBE" bs=1 2>/dev/null
#while IFS="" read -r -n 1 char; do printf '%s' "$char"; done > "$TUBE"

#kill -HUP -$appPID 
kill $appPID

rm -f "$TUBE"
'

1

यह ऐसा करने का सबसे अच्छा तरीका है। आप सर्वर पक्ष पर कुछ चाहते हैं जो स्टडिन को पढ़ने का प्रयास करता है और फिर उस प्रक्रिया समूह को मारता है जब वह विफल हो जाता है, लेकिन आप क्लाइंट पक्ष पर एक स्टडेन भी चाहते हैं जो तब तक ब्लॉक होता है जब तक कि सर्वर साइड प्रक्रिया नहीं हो जाती है और लिंगरिंग प्रक्रियाओं को नहीं छोड़ेगा <( नींद अनंत) हो सकता है।

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

यह वास्तव में कहीं भी stdout को पुनर्निर्देशित करने के लिए प्रतीत नहीं होता है, लेकिन यह एक अवरुद्ध इनपुट के रूप में कार्य करता है और कीस्ट्रोक्स पर कब्जा करने से बचता है।

प्रासंगिक खुलता बग: https://bugzilla.mindrot.org/show_bug.cgi?id=396##14


0

यदि आप उसे (डिफॉल्ट रूप से डिफॉल्ट-बिहेवियर) डिसेबल करना चाहते हैं, तो आपको क्लाइंट या सर्वर-साइड पर ssh-keep-live को सक्षम करना होगा ।

यदि आप मानव-पृष्ठों में ssh-keep-ज़िंदा-विकल्प को देखते हैं, तो आप देख सकते हैं कि वे डिफ़ॉल्ट रूप से अक्षम हैं।


0

मेरा उत्तर टेरू पर आधारित है। मुझे ~/helperसर्वर server.ip पर एक सहायक स्क्रिप्ट की आवश्यकता है :

#!/bin/bash
TUBE=/tmp/sshCoLab_myfifo.$$;
mkfifo "$TUBE"
( <"$TUBE" "$@" ; rm "$TUBE" ; kill -TERM 0 ) &  
cat >"$TUBE" ;
rm "$TUBE" ;
kill -TERM 0 ;

अगर इसे कहा जाता है जैसे

ssh server.ip ~/helper echo hello from server

और echo hello from serverserver.ip पर निष्पादित होता है, और तब ssh क्लाइंट समाप्त हो जाएगा।

अगर इसे कहा जाता है जैसे

ssh server.ip ~/helper sleep 1000 &
CHID=$!

kill -9 $CHIDसर्वर पर स्क्रिप्ट को भी रोक देगा। मेरे लिए, kill -INT $CHIDकाम नहीं करता है, लेकिन मुझे नहीं पता कि क्यों।

टेरू के जवाब में, ssh कमांड हमेशा इंतजार करेगी जब रिमोट कमांड खत्म हो जाएगी, क्योंकि catकभी खत्म नहीं होगी।

Ssh -t के साथ सभी उत्तर मेरे साथ काम नहीं करते थे kill, लेकिन केवल Ctrl-C के साथ।

संपादित करें: मुझे पता चला कि यह एक नए उबंटू 14.01 से एक बड़े वैज्ञानिक लिनक्स बॉक्स में काम करता है - लेकिन दूसरे तरीके से नहीं। इस प्रकार, मुझे लगता है कि कोई सामान्य समाधान नहीं है। अजीब।

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