कई सर्वरों पर SSH पर स्वचालित रूप से कमांड चलाएं


46

.Txt फ़ाइल में IP पतों की एक सूची है, उदा .:

1.1.1.1
2.2.2.2
3.3.3.3

प्रत्येक IP पते के पीछे एक सर्वर होता है, और प्रत्येक सर्वर पर पोर्ट 22 पर चलने वाला sshd होता है। प्रत्येक सर्वर known_hostsसूची में नहीं है (मेरे पीसी, Ubuntu 10.04 LTS / bash पर)।

मैं इन सर्वरों पर कमांड कैसे चला सकता हूं, और आउटपुट इकट्ठा कर सकता हूं?

आदर्श रूप में, मैं सभी सर्वरों पर समानांतर में कमांड चलाना चाहता हूं।

मैं सभी सर्वरों पर सार्वजनिक कुंजी प्रमाणीकरण का उपयोग करूंगा।

यहाँ कुछ संभावित नुकसान हैं:

  • Ssh मुझे मेरी known_hostsफ़ाइल के लिए दिए गए सर्वर ssh कुंजी को डालने के लिए प्रेरित करता है ।
  • दिए गए आदेश एक नॉनज़ेरो एग्जिट कोड लौटा सकते हैं, यह दर्शाता है कि आउटपुट संभावित रूप से अमान्य है। मुझे उसे पहचानने की जरूरत है।
  • कनेक्शन किसी दिए गए सर्वर पर स्थापित होने में विफल हो सकता है, उदाहरण के लिए नेटवर्क त्रुटि के कारण।
  • एक समयबाह्य होना चाहिए, यदि कमांड अपेक्षा से अधिक समय तक चलता है या कमांड चलाने के दौरान सर्वर नीचे चला जाता है।

सर्वर AIX / ksh हैं (लेकिन मुझे लगता है कि वास्तव में कोई फर्क नहीं पड़ता।



1
मुझे लगता है कि यह डुप्लिकेट नहीं है, क्योंकि आपके द्वारा उल्लिखित लिंक में SSH भी नहीं है।
लांसबेंस

4
यदि आपने ऐसा नहीं किया है, तो आपको सभी मशीनों पर ssh सर्वर सेट करना चाहिए, जिस मशीन से आप काम करते हैं, उस पर एक निजी / सार्वजनिक कुंजी जोड़ी बनाएं और आगे की पासवर्ड बाधाओं को रोकने के लिए सर्वर पर सार्वजनिक कुंजी को खातों में कॉपी करें। यह मेरे उत्तर के लिए, और @ आसन के लिए भी लागू होता है।
एंथन

जवाबों:


14

यह मानते हुए कि आप pssh या दूसरों को स्थापित करने में सक्षम नहीं हैं, आप कुछ ऐसा कर सकते हैं:

tmpdir=${TMPDIR:-/tmp}/pssh.$$
mkdir -p $tmpdir
count=0
while IFS= read -r userhost; do
    ssh -n -o BatchMode=yes ${userhost} 'uname -a' > ${tmpdir}/${userhost} 2>&1 &
    count=`expr $count + 1`
done < userhost.lst
while [ $count -gt 0 ]; do
    wait $pids
    count=`expr $count - 1`
done
echo "Output for hosts are in $tmpdir"

1
इस स्क्रिप्ट में वास्तव में क्या करना है ?? Ty!
लांसबैन्स

यदि सर्वर कुंजी मेरे know_hosts फ़ाइल में नहीं है तो क्या होगा?
लांसबैन्स

5
स्क्रिप्ट को पृष्ठभूमि में रखने से बाल प्रक्रियाएं बनती हैं। जब कोई बच्चा प्रक्रिया से बाहर निकलता है, तो प्रक्रिया 'स्लॉट' और संसाधन सिस्टम में बने रहते हैं, जब तक कि मूल प्रक्रिया बच्चे से बाहर नहीं निकलती है या माता-पिता प्रक्रिया 'इंतजार' नहीं करते हैं। ये 'अभी भी मौजूद' प्रक्रियाओं द्वारा समाप्त की गई 'ज़ोंबी' प्रक्रिया कहलाती हैं। बच्चे के बाद सफाई करना और संसाधनों को पुनः प्राप्त करना अच्छा व्यवहार है।
अरेज

1
यदि ज्ञात नहीं है, तो वह इसे -o StrictHostKeyChecking=noखराब कर सकता है, लेकिन आप इससे बचने के लिए जोड़ सकते हैं । हालाँकि, सभी सर्वरों को पहले कमांड-लाइन से स्कैन करना बेहतर होता है ताकि होस्ट कीज़ को जोड़ा जा सके।
Arcege

1
जैसा कि मैंने उल्लेख किया है, ssh प्रोग्राम को बैकग्राउंड में डालने के बाद और उसके बाहर निकलने के बाद, संसाधन अभी भी रखे गए हैं। waitआदेश प्रक्रिया की वापसी कोड (कैसे processs से बाहर निकल गया) सहित उन संसाधनों, reclaims। फिर अगर बाद में कार्यक्रम में, आप एक और प्रक्रिया डालते हैं, तो पृष्ठभूमि में एक संपीड़न कहते हैं, और इसके लिए प्रतीक्षा करने की आवश्यकता होती है, फिर इस लूप के बिना, प्रतीक्षा पूर्ण किए गए ssh कार्यक्रमों में से एक को पुनः प्राप्त करेगी, संपीड़न नहीं - जो अभी भी हो सकता है दौड़ते रहो। आपको गलत चाइल्ड प्रोसेस पर रिटर्न स्टेटस मिलेगा। खुद के बाद सफाई करना अच्छा है।
Arcege

61

वहाँ कई उपकरण हैं जो आपको एक ही समय में कई मशीनों पर आदेशों की श्रृंखला को लॉग इन करने और निष्पादित करने की अनुमति देते हैं। यहाँ एक जोड़े हैं:


1
आप सूची में pdsh जोड़ना चाह सकते हैं ।
रिकार्डो मुरी

1
मैंने पाया कि क्लस्टश उपयोग करने के लिए काफी सहज है। बस मेरे 2 सेंट ...
josinalvo

1
मैं अक्सर pssh का उपयोग करता हूं। यह बहुत अच्छी तरह से काम करता है, हालांकि मैं चाहता हूं कि मैं यह बता सकता हूं कि कुछ दूरस्थ कमांड में एक गैर-शून्य निकास कोड होगा, और इसका मतलब यह नहीं है कि कोई त्रुटि है। हालांकि विशुद्ध रूप से कॉस्मेटिक है।
एंथनी क्लार्क

1
@AnthonyClark आप उन आदेशों को "" सही "" कह सकते हैं।
निर्गमन

16

यदि आप स्क्रिप्टिंग से अधिक पायथन में हैं bash, तो फैब्रिक आपके लिए उपकरण हो सकता है।

से कपड़ा मुख पृष्ठ :

फैब्रिक एक पायथन (2.5 या उच्चतर) लाइब्रेरी और कमांड-लाइन टूल है, जो एसएसएच के उपयोग को व्यवस्थित करने के लिए उपयोग करता है।

यह स्थानीय या दूरस्थ शेल कमांड (सामान्य रूप से या sudo के माध्यम से) और फ़ाइलों को अपलोड / डाउनलोड करने के लिए संचालन का एक बुनियादी सूट प्रदान करता है, साथ ही सहायक कार्यक्षमता जैसे इनपुट के लिए रनिंग उपयोगकर्ता को प्रेरित करना, या निष्पादन को समाप्त करना।

विशिष्ट उपयोग में एक पायथन मॉड्यूल बनाना शामिल है जिसमें एक या अधिक फ़ंक्शन होते हैं, फिर उन्हें फैब कमांड-लाइन टूल के माध्यम से निष्पादित करते हैं।


फैब्रिक v1 अद्भुत था। दुर्भाग्य से, फैब्रिक v2 ने उन अधिकांश विशेषताओं को हटा दिया जो इसे इस उपयोग के मामले के लिए उपयोगी बनाती हैं - वर्तमान में (जून 2018) अनुशंसित नहीं होंगी।
मियोकी

11

मैं उस के लिए जीएनयू समानांतर का उपयोग करता हूं, विशेष रूप से आप इस नुस्खा का उपयोग कर सकते हैं :

parallel --tag --nonall --slf your.txt command

साथ your.txtसर्वर आईपी पते / नाम के साथ फ़ाइल जा रहा है।


केवल ssh का उपयोग करने का कोई और तरीका नहीं है क्योंकि मैं अपनी कंपनी के सर्वर का उपयोग कर रहा हूं मैं अतिरिक्त पैकेज स्थापित नहीं करना चाहता हूं
eshzzesh

ज़रूर, मैं ऐसा करने से पहले भी sshमौजूद था, लेकिन आपको दूसरे कंप्यूटरों में लॉगिन करने के लिए कुछ तरीके चाहिए और वे तरीके कम सुरक्षित (जैसे rsh) हुआ करते थे। आप का वर्णन नहीं करते तुम अब क्या प्रयोग कर रहे हैं मशीन से मशीन को पाने के लिए ( telnet?, rsh?)।
एंथन

1
@ Özzesh हाँ केवल नियंत्रक पर
Anthon

1
@ GNzzesh देखें कि GNU समानांतर स्थापित न करने का आपका कारण oletange.blogspot.dk/2013/04/why-not-install-gnu-parallel.html
Ole Tange

1
@OleTange ने महसूस किया कि मेरे उत्तर पर कौन टिप्पणी करता है -)। सॉफ्टवेयर के इस उत्कृष्ट टुकड़े के लिए धन्यवाद।
एंथन

8

बहुत मूल सेटअप:

for host in $(cat hosts.txt); do ssh "$host" "$command" >"output.$host"; done

नाम / पासवर्ड के साथ प्रमाणीकरण वास्तव में कोई अच्छा विचार नहीं है। आपको इसके लिए एक निजी कुंजी सेट करनी चाहिए:

ssh-keygen && for host in $(cat hosts.txt); do ssh-copy-id $host; done

1
यह वही है जिसकी मुझे तलाश है !!!!! धन्यवाद मिशा
eshसुशेश

उपरोक्त स्क्रिप्ट मेरे लिए अच्छी तरह से काम करती है लेकिन 10 सर्वर में निष्पादित करने के बाद स्क्रिप्ट प्रतिक्रिया नहीं देती है। मैं ssh सर्वर को कैसे लॉगआउट कर सकता हूं, जिससे मैं जुड़ा हुआ हूं?
.जेश

आपको स्पष्ट रूप से लॉगआउट करने की आवश्यकता नहीं होनी चाहिए। यह "स्क्रिप्ट" बस ssh $host $commandप्रत्येक मेजबान के लिए चलेगी । उन आदेशों को मैन्युअल रूप से चलाने का प्रयास करें कि क्या हो रहा है।
michas


2

मुझे लगता है कि आप pssh और सामान्य scp, rsync, आदि के संबंधित समानांतर संस्करणों की तलाश कर रहे हैं ।


यह डिलीट होने से एक वोट दूर है, लेकिन बाद में इसका जवाब +10 पर है। सही समझ में आता है
माइकल Mrozek

@MichaelMrozek यह आप जानते से भी बदतर है। दो वीटीडी का दूसरा एक क्लिक-हैप्पी-दुर्घटना पर मेरा है। अगर यह हटाए जाने के बाद मैंने अपने वीटीडी को वापस करने के लिए झंडा या पिंग करने का इरादा किया है, तो मुझे यह टैब कुछ दिनों के लिए खुला है। हो सकता है कि आप वोटों को साफ़ करने के लिए इसे अभी फ्लिप कर सकें।
कालेब

@Caleb यह फिक्स्ड
माइकल Mrozek

2

मैंने इस तरह की चीज़ को आसान बनाने के लिए ओवरकास्ट नामक एक ओपन-सोर्स टूल बनाया ।

सबसे पहले आप अपने सर्वर को परिभाषित करते हैं:

overcast import vm.01 --ip 1.1.1.1 --ssh-key /path/to/key
overcast import vm.02 --ip 2.2.2.2 --ssh-key /path/to/key

फिर आप उन पर कई कमांड और स्क्रिप्ट फ़ाइलों को चला सकते हैं, या तो क्रमिक रूप से या समानांतर में, जैसे:

overcast run vm.* uptime "free -m" /path/to/script --parallel

2

Hypertable परियोजना हाल ही में एक बहु मेजबान ssh उपकरण जोड़ा गया है। यह टूल लिबास के साथ बनाया गया है और कनेक्शन स्थापित करता है और समवर्ती रूप से और अधिकतम समानता के लिए समांतर मुद्दों को जारी करता है। पूर्ण प्रलेखन के लिए मल्टी-होस्ट एसएसएच टूल देखें । मेजबानों के सेट पर एक कमांड चलाने के लिए, आप इसे निम्नानुसार चलाएंगे:

$ ht ssh 1.1.1.1,2.2.2.2,3.3.3.3 uptime

आप एक होस्ट नाम या आईपी पैटर्न भी निर्दिष्ट कर सकते हैं, उदाहरण के लिए:

$ ht ssh 1.1.1.[1-99] uptime
$ ht ssh host[00-99] uptime

यह एक --random-start-delay <millis>विकल्प का भी समर्थन करता है जो प्रत्येक होस्ट पर कमांड की शुरुआत को 0 और <millis>मिलीसेकंड के बीच यादृच्छिक समय अंतराल से शुरू करने में देरी करेगा । यह विकल्प झुंड समस्याओं से बचने के लिए इस्तेमाल किया जा सकता है जब कमांड चलाया जा रहा है केंद्रीय संसाधन तक पहुंचता है।


2

मैंने कई सर्वरों में निष्पादित कार्यों को प्राप्त करने के लिए बहुत सरल और प्रभावी कलेक्टनोड विकसित किया है (विंडोज़ में शामिल हैं)

कलेक्शनकोड का उपयोग कैसे करें:

  1. सर्वर की सूची बनाएं, इसके साथ काम करने के लिए:

    # cat hosts.file
    server1
    server2
    server3
    server4
    server5
    
  2. कार्य की सूची पास करने वाले कलेक्टनोड निष्पादित करें:

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User'
    
  3. वैकल्पिक रूप से, परिणामों को फ़िल्टर करना संभव है, उदाहरण के लिए यह कमांड केवल उस सर्वर को प्रदर्शित करता है जहां स्थिति पूरी होती है।

    collectnode --file servers.txt --command='cat /etc/httpd/conf/httpd.conf |grep ^User' --where="command contain User"
    

https://collectnode.com/5-tasks-collectnode-can-help-managing-servers/


1
ऐसा लगता है कि आप कलेक्टनोड के डेवलपर हैं। उस स्थिति में, आपको यह खुलासा करना चाहिए कि उत्तर में या यह सिर्फ स्पैम है।
मुरु

क्षमा करें, यह मेरा उद्देश्य नहीं था, और अधिक विशिष्ट होने के लिए संशोधित उत्तर।
fvidalmolina

1

बस एक बहुत अच्छा सवाल के लिए एक हेडअप:

सबसे अच्छा समाधान जो मैंने पाया है, वह आश्चर्यजनक रूप से नहीं, tmux है।

आप Ctrl-B कर सकते हैं: अद्भुत resut के लिए tmux में सिंक्रोनाइज़-पैन सेट करें। आपके पास आपके सभी ssh कनेक्शन खुले होने चाहिए, इसके लिए Tmux की 1 विंडो के विभिन्न पैन में।


0

शायद इस तरह से कुछ काम करता है, कई मेजबानों पर कमांड चलाने के लिए? मान लें कि सभी होस्ट पासवर्ड-कम लॉगिन के लिए .ssh / config में सेटअप हैं।

$ < hosts.txt xargs -I {} ssh {} command


0

एक फ़ाइल / etc / sxx / मेजबान बनाएँ

ऐसे आबाद करें:

[grp_ips]
1.1.1.1
2.2.2.2
3.3.3.3

सभी मशीनों पर ssh कुंजी साझा करें।

पैकेज से sxx स्थापित करें:

https://github.com/ericcurtin/sxx/releases

फिर कमांड को ऐसे चलाएं:

sxx username@grp_ips "whatever bash command"

आउटपुट कहाँ लिखा गया है? गैर-शून्य निकास स्थिति कैसे नियंत्रित की जाती है? कृपया टिप्पणियों में प्रतिक्रिया न दें; इसे स्पष्ट और अधिक पूर्ण बनाने के लिए अपना उत्तर संपादित करें।
जी-मैन का कहना है कि 'मोनिका'

0

Paramiko http://www.paramiko.org/ और थ्रेड-आधारित समानता का उपयोग करें https://docs.python.org/3/library.threading.html .below कोड समानांतर में प्रत्येक सर्वर पर कई कमांड निष्पादित करने की अनुमति देता है!

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.load_system_host_keys()
ssh.connect(hostname, port, username, password)
t = threading.Thread(target=tasks[index], args=(ssh, box_ip,))
t.start()

नोट: प्रत्येक सर्वर के निर्देशों के ऊपर दोहराएं।


0

मुझे लगता है कि "अपेक्षा" वही है जो आपको चाहिए।
बहुत से लोग यह भी नहीं जानते कि यह मौजूद है। यह एक tcl आधारित कार्यक्रम है जो आपकी ओर से प्रश्न और संभावित उत्तर देगा। Https://wiki.tcl-lang.org/page/Expect पर नज़र डालें

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