लूप को रोकने के लिए SSH का कारण बनता है


30

मैं अंत में एक समस्या से उबने में कामयाब रहा हूं जो मैं कुछ हफ्तों से संघर्ष कर रहा था। मैं दूरस्थ रूप से कमांड चलाने के लिए "अधिकृत कुंजी" के साथ SSH का उपयोग करता हूं। जब मैं थोड़ी देर के पाश में करता हूं, तब तक सब ठीक है। पाश एक ssh कमांड के साथ किसी भी पुनरावृत्ति को पूरा करने के बाद समाप्त होता है।

लंबे समय तक मुझे लगा कि यह किसी प्रकार की ksh अजीबता है, लेकिन मैंने अब खोजा है कि वास्तव में bash क्या पहचान का व्यवहार करता है।

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

#!/bin/bash

set -x

IDTAG=".*zone"
MARKER="mark-$(date +%Y.%m.%d.%H.%M.%S)"
REMOTE_HOST=sol10-target
ZFSPARENT=rpool

ssh $REMOTE_HOST zfs list -t filesystem -rHo name,mounted $ZFSPARENT | grep "/$IDTAG    " > /tmp/actionlist

#for RMT_FILESYSTEM in $(cat /tmp/actionlist)
cat /tmp/actionlist | while read RMT_FILESYSTEM ISMOUNTED
do
   echo ${RMT_FILESYSTEM}@${MARKER}
   [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
   echo Remote Command Return Code: $?
done

(नोट: zfs सूची "-H" विकल्प के व्यवहार की परिभाषा के अनुसार grep खोज अभिव्यक्ति में एक TAB वर्ण है।)

मेरे नमूने में रूट के लिए कुछ ZFS फाइल सिस्टम हैं जहाँ सभी "ज़ोन" में एक समान नाम वाले डेटासेट पर अपना रूट फाइल सिस्टम है।

POOL / क्षेत्र / app1zone
POOL / क्षेत्र / समूह 2 / app2zone

आदि।

उपरोक्त लूप को प्रत्येक चयनित डेटासेट के लिए एक स्नैपशॉट बनाना चाहिए, लेकिन इसके बजाय यह केवल पहले एक पर काम करता है और फिर बाहर निकलता है।

यह प्रोग्राम पाता है कि स्क्रिप्ट मौजूद होने के बाद डेटासेट की सही संख्या "/ tmp / एक्शनलिस्ट" फ़ाइल की जांच करके आसानी से पुष्टि की जा सकती है।

यदि ssh कमांड को प्रतिस्थापित किया जाता है, उदाहरण के लिए, एक इको कमांड, तो लूप सभी इनपुट लाइनों के माध्यम से पुनरावृत्त करता है। या मेरे पसंदीदा - अपमानजनक आदेश के लिए "प्रतिध्वनि" प्रस्तुत करना।

यदि मैं लगातार लूप के लिए उपयोग करता हूं तो यह भी काम करता है, लेकिन डेटासेट की सूची के संभावित आकार के कारण यह अधिकतम विस्तारित कमांड लाइन की लंबाई के साथ समस्याएं पैदा कर सकता है।

मुझे अब 99.999% यकीन है कि उन में ssh कमांड वाले केवल लूप मुझे समस्याएं देते हैं!

ध्यान दें कि वह क्रम जिसमें ssh कमांड चलता है, पूरा होता है! यह ऐसा है जैसे डेटा लूप में आने के दौरान अचानक खो जाता है ... यदि पहली कुछ इनपुट लाइनें ssh कमांड नहीं करती हैं, तो लूप तब तक चलता है जब तक वह वास्तव में SSH कमांड को रन नहीं करता है।

मेरे लैपटॉप पर जहां मैं यह परीक्षण कर रहा हूं, मेरे पास दो सोलारिस 10 वीएम हैं जिनमें केवल दो या तीन सैंपल डेटासेट हैं, लेकिन वही बड़े स्पार्क सिस्टम पर हो रहा है, जहां यह लाइव होने के लिए है, और कई डेटासेट हैं।


7
SSH मानक इनपुट से पढ़ सकता है, खा सकता है आपका actionlist। Ssh के मानक इनपुट को पुनर्निर्देशित करने का प्रयास करें/dev/null
बैच 37

मैं कोशिश करूंगा कि मैं जोड़ना चाहता हूं कि एक रैपर में ssh डालना मदद नहीं करता है ....
जोहान

तुम सही हो। मैं ऐसा कैसे नहीं देख सकता !?
जोहान

@ बैच मुझे लगता है कि आपकी टिप्पणी एक जवाब के रूप में योग्य है।
एक CVn

मैं सहमत हूं कि मैं उत्तर को "स्वीकार" करना चाहूंगा यदि @ बैचैएक्स इसे फिर से तैयार कर सकता है जैसे कि मैं ऐसा करूंगा।
जोहान

जवाबों:


43

SSH मानक इनपुट से पढ़ सकता है, आपके एक्शनलिस्ट को खा सकता है। Ssh के मानक इनपुट को / dev / null पर पुनर्निर्देशित करने का प्रयास करें:

ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER} </dev/null

एक सामान्य नियम के रूप में, जब कमांड चलती है जो एक while read-स्टाइल लूप के तहत मानक इनपुट में हस्तक्षेप कर सकती है , तो मैं पूरे लूप बॉडी को ब्रेस में लपेटना पसंद करता हूं:

cat /tmp/uuoc | while read RMT_FILESYSTEM ISMOUNTED
do {
    echo ${RMT_FILESYSTEM}@${MARKER}
    [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
    echo Remote Command Return Code: $?
} < /dev/null; done

3
पहले घुंघराले ब्रेसिज़ के विशिष्ट उपयोग के लिए डबल भयानक ... जो मेरे पास 20 वर्षों की स्क्रिप्टिंग में कभी भी सामना नहीं किया गया (कम से कम ऐसा नहीं है कि मैं याद रख सकता हूं।) और उकसाव के लिए। FWIW (और अपनी खुद की रक्षा में) मैं कभी-कभी एक अपवाद बनाता हूं और पठनीयता के लिए निरर्थक कैट स्टेटमेंट जोड़ता हूं! मुझे इस मंच से प्यार है क्योंकि मैं अचानक फिर से नई चीजें सीख रहा हूं! विशेष रूप से मुझे इस मामले की तरह लाइनों की शुरुआत में रीडायरेक्ट जोड़ना पसंद है, लेकिन मंचों पर जो इस मामले को भ्रमित करने के लिए लगता है, जिससे मुझे कम उपयोगी प्रतिक्रियाएं मिल सकती हैं!
जोहान

मैं {...} और (...) ksh मैन पेज के बीच के अंतर को जानने की कोशिश कर रहा हूं। {...} विशेष कीवर्ड केवल कमांड लाइन की शुरुआत में पहचाने जाते हैं। लेकिन एक और अंतर है ... ( </tmp/file [ -z "$SOMEVAR" ] && awk '{print "X", $0}' )घुंघराले ब्रेसिज़ के साथ समान है। मैं उत्पादित आउटपुट के संदर्भ में हूं, इस तथ्य के बारे में नहीं कि बंद घुंघराले ब्रेस एक नई लाइन पर होना चाहिए ...
जोहान

5
इसके अलावा, OpenSSH के ssh के पास -nविकल्प है जो इसे (प्रभावी रूप से) / स्टड को / dev / null से फिर से खोल देता है।
क्रिस जॉन्सन

sudoलूप के अंदर कमांड के साथ उपयोग करने के लिए कोई वर्कअराउंड ?
bon

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