दूरस्थ कमांड निष्पादित करें, ssh कनेक्शन से पूरी तरह से अलग


48

मेरे पास 2 कंप्यूटर हैं, localpcऔर remoteserver

मुझे localpcकुछ कमांड निष्पादित करने की आवश्यकता है remoteserver। इसके लिए आवश्यक चीजों में से एक बैकअप स्क्रिप्ट शुरू करना है जो कई घंटों तक चलती है। मैं चाहता हूं कि localpc"आग" पर कमांड हो और फिर पूरी तरह से स्वतंत्र हो remoteserver, जैसे localpcपहले कभी नहीं था।

मैंने अब तक यही किया है:

remoteserver इसमें स्क्रिप्ट है:

/root/backup.sh

localpc इसे चलाने के लिए निर्धारित है:

ssh root@remoteserver 'nohup /root/backup.sh' &

क्या मैं इसे सही तरीके से कर रहा हूं? क्या ऐसा करने के लिए इससे अच्छा तरीका है? क्या मैं इसे इस तरह से करने में किसी परेशानी में रहूंगा?


stackoverflow.com/questions/19996089/… और stackoverflow.com/questions/29142/… स्क्रीन / tmux आदि का उपयोग नहीं करने के लिए इस समस्या के लिए कई उपयोगी दृष्टिकोण प्रदान करते हैं ...
पॉल

जवाबों:


47

आपको संभवतः screenदूरस्थ होस्ट पर उपयोग करना चाहिए , एक वास्तविक अलग कमांड के लिए:

ssh root@remoteserver screen -d -m ./script

मुझे यह विचार पसंद है। जब स्क्रिप्ट पूरी हो जाएगी, तब भी स्क्रीन चालू रहेगी ... और मुझे अगली बार इसे फिर से कनेक्ट करना होगा, मैं इसे चलाना चाहता हूं, है ना?
LVLAaron

@AaronJAnderson: नहीं, यह देखते हुए कि कमांड एक शेल नहीं है, जब यह स्क्रीन सत्र भी समाप्त हो जाता है।
enzotib

52

बंद करें, लेकिन बिल्कुल नहीं।

किसी भी टर्मिनल का स्वतंत्र रूप से

ssh root@remoteserver '/root/backup.sh </dev/null >/var/log/root-backup.log 2>&1 &'

आपको सभी फ़ाइल डिस्क्रिप्टर को बंद करने की आवश्यकता है जो ssh सॉकेट से जुड़े हैं, क्योंकि ssh सत्र बंद नहीं होगा जब तक कि कुछ दूरस्थ प्रक्रिया में सॉकेट खुला रहता है। यदि आपको स्क्रिप्ट के आउटपुट में दिलचस्पी नहीं है (संभवत: क्योंकि स्क्रिप्ट ही लॉग फ़ाइल में लिखने का ख्याल रखती है), तो इसे रीडायरेक्ट करें /dev/null(लेकिन ध्यान दें कि यह त्रुटियों को छिपा देगा जैसे कि स्क्रिप्ट शुरू करने में सक्षम नहीं है)।

उपयोग करने nohupका यहाँ कोई उपयोगी प्रभाव नहीं है। nohupयदि प्रोग्राम का कंट्रोलिंग टर्मिनल गायब हो जाता है, तो प्रोग्राम के लिए यह HUP सिग्नल प्राप्त करने के लिए नहीं चलता है, लेकिन यहाँ पहले से कोई टर्मिनल नहीं है, इसलिए नीले रंग से बाहर की प्रक्रिया के लिए कुछ भी नहीं भेजा जा रहा है। इसके अलावा, nohupमानक आउटपुट और मानक त्रुटि (लेकिन मानक इनपुट नहीं) को एक फ़ाइल पर पुनर्निर्देशित करता है, लेकिन केवल अगर वे एक टर्मिनल से जुड़े हैं, जो फिर से, वे नहीं हैं।

एक टर्मिनल से कोचिंग

 aaron@localpc$ ssh root@remoteserver
 root@remoteserver# nohup /root/backup.sh </dev/null &
 nohup: appending output to `nohup.out'
 [1] 12345
 root@remoteserver# exit
 aaron@localpc$ 

का प्रयोग करें nohupअपने नियंत्रण टर्मिनल से स्क्रिप्ट अलग करने इतना है कि यह एक प्राप्त नहीं होता है SIGHUP जब टर्मिनल गायब हो जाता है। nohupस्क्रिप्ट के मानक आउटपुट और मानक त्रुटि को एक फ़ाइल में रीडायरेक्ट करता है जिसे nohup.outवे टर्मिनल से जुड़े हुए हैं; आपको स्वयं मानक इनपुट का ध्यान रखना होगा।

रिमोट टर्मिनल रखना

यदि आप कमांड को रिमोट टर्मिनल में रखना चाहते हैं, लेकिन यह SSH सत्र से जुड़ा नहीं है, तो इसे स्क्रीन या Tmux जैसे टर्मिनल मल्टीप्लेक्स में चलाएं

ssh root@remoteserver 'screen -S backup -d -m /root/backup.sh'

आप बाद में screen -S backup -rdउस मशीन पर रूट के रूप में इनवॉइस चलाकर उस टर्मिनल को फिर से कनेक्ट कर सकते हैं ।

एक दूरस्थ कमांड को स्वचालित करना

थोड़ी बेहतर सुरक्षा के लिए, सीधे दूरस्थ रूट लॉगिन को भी व्यापक रूप से न खोलें। एक विशेष-उद्देश्य वाली कुंजी जोड़ी बनाएं और इसे एक मजबूर कमांड दें /root/.ssh/authorized_keys। सार्वजनिक कुंजी फ़ाइल की सामग्री है AAAA…== wibble@example.com; उन विकल्पों की अल्पविराम से अलग सूची जोड़ें, command="…"जिसमें यह निर्दिष्ट किया गया है कि कुंजी का उपयोग केवल इस विशिष्ट कमांड को निष्पादित करने के लिए किया जा सकता है। सभी विकल्पों और कुंजी को एक पंक्ति में रखना सुनिश्चित करें।

command="/root/backup.sh </dev/null >/dev/null 2>/dev/null &",no-port-forwarding,no-agent-forwarding,no-x11-forwarding,no-pty,no-user-rc AAAA…== wibble@example.com

मैंने आपके द्वारा सूचीबद्ध पहली कमांड की कोशिश की है। यह उस बॉक्स पर पृष्ठभूमि नहीं करता है जिसने कमांड निष्पादित किया है। कर्सर बस वहां बैठता है और पूरा होने का इंतजार करता है ... शायद यह एक बग है?
LVLAaron

आपको रिमोट सिस्टम पर स्टड को / dev / null में रीडायरेक्ट करने की आवश्यकता हो सकती है। यही कारण है कि ssh बाहर नहीं निकल रहा है।
कीथबी

मैं -fस्थानीय पक्ष में 'बैकग्राउंड' (यानी समाप्त, निकट संबंध) के लिए ssh पाने का विकल्प जोड़ूंगा। यह के साथ संयोजन के रूप में काम करेगा &nohupइस मामले में वैकल्पिक है, लेकिन आप setsidइसके बजाय उपयोग करने पर विचार कर सकते हैं ।
अलेक्सियो

@KeithB रीडायरेक्टिंग स्टड इसका एक हिस्सा है, लेकिन मुझे stdout और stderr को रीडायरेक्ट करने की भी आवश्यकता है: nohup यहाँ ऐसा नहीं करेगा क्योंकि वे टर्मिनल नहीं हैं, और वास्तव में nohup यहाँ उपयोगी नहीं है।
गिल्स एसओ- बुराई को रोकें '

1
@erikbwork कृपया ध्यान दें कि मेरे पास उन चीजों के बारे में बिल्कुल कोई सुराग नहीं है, लेकिन चर्चा और टिप्पणियों का पालन करते हुए: गिल्स अपने आदेशों में -t विकल्प का उपयोग नहीं करते हैं, इसलिए कोई छद्म टर्मिनल स्थापित नहीं किया जाएगा, न तो क्लाइंट पर और न ही सर्वर पर पक्ष। इसलिए, कोई एचयूपी नहीं भेजा जाएगा।
बिनारस

12

SSH जैसे दूरस्थ लॉगिन से रिमोट कमांड चलाने का मानक नुस्खा निम्नलिखित है:

nohup command </dev/null >command.log 2>&1 &

यदि commandएक खोल स्क्रिप्ट है कि एक फ़ाइल स्वयं करने के लिए लॉगिंग का ध्यान रखता है, तो आप को बदल सकता है command.logके लिए /dev/null। एक बार जब आप इसे शुरू करते हैं, तो तुरंत लॉग ऑफ करें।

आपको उस लाइन पर सब कुछ चाहिए।

nohup यदि लॉगिन सत्र डिस्कनेक्ट हो जाता है, तो शेल को प्रक्रिया को परेशान नहीं करने के लिए कहता है।

</dev/null यह बताता है कि इनपुट के लिए कभी इंतजार नहीं करना चाहिए

>command.log इसे इस लॉग फ़ाइल में कोई भी संदेश भेजने के लिए कहता है

2>&1यह किसी भी stderr संदेशों को उसी लॉग फ़ाइल में भेजने के लिए कहता है। कुछ मामलों में दो फाइलें रखना बेहतर है, दूसरा त्रुटि संदेश एकत्र करने के लिए, और सामान्य गतिविधि संदेश एकत्र करने के लिए पहला। इससे यह सत्यापित करना आसान हो जाता है कि सब कुछ सही तरीके से काम कर रहा है।

& इसे इस प्रक्रिया को अलग करने और इसे पृष्ठभूमि प्रक्रिया के रूप में चलाने के लिए कहता है।


10

यह धागा बहुत मददगार था लेकिन मेरा समाधान थोड़ा अलग होना था।

मुझे स्क्रीन सॉल्यूशन पसंद नहीं है क्योंकि यह एक स्क्रीन प्रोसेस को छोड़ देता है जिसकी मुझे ज़रूरत नहीं है। पुनर्निर्देशन और nohups इस तरह इस्तेमाल किया:

ssh root@remoteserver '/root/backup.sh </dev/null >/var/log/root-backup.log 2>&1 &'

जब ssh कमांड के साथ प्रयोग किया गया तो मेरे लिए काम नहीं कर रहा था।

मैंने रिमोट मशीन पर एक रैपर स्क्रिप्ट बनाई जो वास्तविक स्क्रिप्ट चलाती है। रैपर स्क्रिप्ट रीडायरेक्शन और नूप को सेट करता है। कुछ इस तरह:

backupwrapper.sh:
nohup backup.sh > /dev/null 2>&1 &

फिर मेरे क्लाइंट मशीन पर मैं (नोटिस नो रिडायरेक्शन) चलाता हूं:

# ssh remotemachine "backupwrapper.sh"
#

Ssh कमांड तुरंत लौटता है, कनेक्शन समाप्त हो जाता है और स्क्रिप्ट को छोड़ दिया जाता है।


6

जैसा कि निल्स कहते हैं , यह एक सुरक्षा जोखिम है जो रूट को ssh के माध्यम से लॉग इन करने की अनुमति देता है। और मैं एक लॉग के बिना मशीन पर कोई भी पर्याप्त काम चलाने के खिलाफ सलाह देता हूं। यदि कुछ भी गलत होता है, तो आप चाहते हैं कि आपके पास कुछ समस्या निवारण संदेश हों। आपको यह दिखाने के लिए अन्य उत्तर हैं। लेकिन यहाँ मैं कैसे आप के लिए पूछा पूरा करने की सलाह है। यह सब sh (1) में बनाया गया है। GNU स्क्रीन की कोई आवश्यकता नहीं है (हालाँकि मुझे लगता है कि यह एक चतुर समाधान है)। इस स्ट्रिंग को अपनी कमांड में जोड़ें >&- 2>&- <&- &:। >&-मतलब स्टडआउट। 2>&-पास का मतलब। <&-पास का मतलब है। &मतलब पृष्ठभूमि में चलता है, जैसे

$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$

0

आपको दूरस्थ कमांड को पृष्ठभूमि में रखना चाहिए remoteserver। जिस तरह से आप इसे करेंगे, वह ssh- कमांड को बैकग्राउंड करेगा localpc

इसके अलावा रूट-एसश को अनुमति देना एक बुरा विचार है।

तो सेटअप पर remoteserver: एक sudoers लाइन जो /root/backup.shउपयोगकर्ता द्वारा रूट के रूप में चलेगी backup

आप "अच्छा" पासवर्ड के बिना उस उपयोगकर्ता को बना सकते हैं।

कमांड sudo /root/backup.sh &को कमांड के रूप में रखें ~backup/.ssh/authorized_keys- साथ में सार्वजनिक कुंजी से localpc(जो भी उस स्क्रिप्ट को चलाता है)।


-1
#screen -d -m -S BACKUP ssh root@remoteserver /root/backup.sh

2
यह बहुत उपयोगी नहीं है: यदि एसएसएच कनेक्शन मर जाता है, तो स्क्रिप्ट का स्टडआउट और स्टडर बंद हो जाएगा, जिससे परेशानी हो सकती है। स्क्रीन को दूरस्थ मशीन पर चलाया जाना चाहिए (जैसा कि एनज़ोटिब के उत्तर में )।
गिल्स एसओ- बुराई को रोकें '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.