आप सफलता मिलने तक कैसे काम चला सकते हैं


237

मेरे पास एक स्क्रिप्ट है और उपयोगकर्ता से कुछ जानकारी मांगना चाहते हैं, स्क्रिप्ट तब तक जारी नहीं रह सकती जब तक उपयोगकर्ता इस जानकारी को नहीं भरता। इसे प्राप्त करने के लिए कमांड को एक लूप में रखने का मेरा प्रयास है, लेकिन यह किसी कारण से काम नहीं करता है।

echo "Please change password"
while passwd
do
echo "Try again"
done

मैंने लूप के कई रूपों की कोशिश की है:

while `passwd`
while [[ "`passwd`" -gt 0 ]]
while [ `passwd` -ne 0 ]]
# ... And much more

लेकिन मुझे लगता है कि यह काम करने के लिए नहीं मिल सकता है।

जवाबों:


403
until passwd
do
  echo "Try again"
done

या

while ! passwd
do
  echo "Try again"
done

20
इसमें से Ctrl-C के लिए मुश्किल।
डॉनगर

यदि आपको लगता है कि आपको इसे रद्द करने की आवश्यकता है, तो बस अपने शेल का एक नया उदाहरण खोलें (उदाहरण के लिए, "बैश" टाइप करें) और, जब आप इसे रद्द करना चाहते हैं, तो किसी अन्य टर्मिनल विंडो में जाएं और नव स्पैश बैश को मारें प्रक्रिया।
एथन

50
इस से बाहर सीटीआर-सी के लिए आसान: until passwd; do echo "Try again"; sleep 2; done- आपको बस इतना करना है कि सीटीआर-सी को प्रेस करें (दो सेकंड के भीतर) echoयह काम किया है।
ईसाई

9
@azmeuk: कुछ इस तरह आज़माएं until passwd || (( count++ >= 5 )); do echo "foo"; done(केवल बैश करें, गिनती 0 पर सेट करें अगर यह वैरिएबल मौजूद है तो) यदि आपको सादे श के लिए इसकी आवश्यकता है, तो शरीर में काउंटर को बढ़ाएँ और उपयोग करें []
जस्टिन साने

2
इस पृष्ठ का कई बार उल्लेख करने के बाद, मैंने आदेशों को पुनः प्राप्त करने के लिए एक जेनेरिक बैश फ़ंक्शन बनाने का निर्णय लिया, यहाँ यह है: gist.github.com/felipou/6fbec22c4e04d3adfae5
Felipou

94

आपको $?इसके बजाय परीक्षण करने की आवश्यकता है , जो पिछले कमांड की निकास स्थिति है। passwd0 के साथ बाहर निकलता है अगर सब कुछ ठीक काम किया है, और गैर-शून्य अगर पासवार्ड परिवर्तन विफल हुआ (गलत पासवर्ड, पासवर्ड बेमेल, आदि ...)

passwd
while [ $? -ne 0 ]; do
    passwd
done

अपने बैकटिक संस्करण के साथ, आप पासवर्ड के उत्पादन, जो की तरह सामान होगा तुलना कर रहे हैं Enter passwordऔर confirm passwordऔर की तरह।


2
ऐसा नहीं होना चाहिए $??
शॉन चिन

मुझे यह पसंद है क्योंकि यह स्पष्ट है कि विपरीत परिस्थिति के लिए इसे कैसे अनुकूलित किया जाए। उदाहरण के लिए एक गैर-नियतात्मक बग के साथ एक कार्यक्रम चलाएं जब तक कि यह विफल नहीं हो जाता
एरिक

जब गैर-शून्य निकास कोड द्वारा सफलता का संकेत दिया जाता है, तो आपको यही चाहिए।
गुडालुगुर एगिल्सन

2
मैं इस से थोड़ा पहले बदलकर पर सुधार किया जा सकता है लगता है passwdके साथ /bin/falseअगर आप कुछ लंबी और जटिल आदेश है कि आप के दो संस्करणों को रखने के लिए नहीं करना चाहती है।
बृहस्पतिवार

स्वीकृत उत्तर इम्हो होना चाहिए। यह अधिकांश गोले (बाश, मक्ष और राख में परीक्षण) में काम करना चाहिए और आसानी से स्थिति के अनुकूल है।
लिन्यूकेन्ड्रिया

73

@ मर्क बी के जवाब पर विस्तार से जानने के लिए,

$ passwd
$ while [ $? -ne 0 ]; do !!; done

एक ही काम करने का अच्छा तरीका है जो विशिष्ट नहीं है।


11
दुर्भाग्य से मेरे लिए काम नहीं करता (मुझे मिलता है '!!' कमांड नहीं मिला)। यह कैसे काम करने वाला है?
जोहान्स रूडोल्फ

2
यह पिछली कमांड को चलाने के लिए एक बैश ट्रिक है। उदाहरण के लिए यदि आप sudoकमांड के सामने लिखना भूल जाते हैं , तो आप sudo !!रूट कमांड को रूट विशेषाधिकार के साथ चला सकते हैं ।
JohnEye

1
क्या मैं अपनी प्रोफ़ाइल में एक स्क्रिप्ट बना सकता हूं जो ऐसा कर सके, इसलिए मैं जा सकता हूं: $ makelastwork
user230910

2
रनों के बीच कैसे सोना है?
कामिल डेजिडिक

6

इसे प्राप्त करने के लिए आप एक अनंत लूप का उपयोग कर सकते हैं:

while true
do
  read -p "Enter password" passwd
  case "$passwd" in
    <some good condition> ) break;;
  esac
done

2
यह एकमात्र उत्तर है जिसे किसी फ़ंक्शन में मेरी बहु-पंक्ति कमांड डालने की आवश्यकता नहीं है। मैंने && breakअपने सत्यापन आदेश के बाद किया था, हालांकि चयनित मामले के बजाय।
carlin.scott

4

अगर किसी के पास रिट्रीट सीमा है:

max_retry=5
counter=0
until $command
do
   sleep 1
   [[ counter -eq $max_retry ]] && echo "Failed!" && exit 1
   echo "Trying again. Try #$counter"
   ((counter++))
done

1
until $(command)मूल रूप से हमेशा गलत है। until commandइसके बजाय उपयोग करें । $(...)का कारण बनता है उत्पादन की commandअपने आप में एक आदेश के रूप में चलाने होने के लिए, और के निकास स्थिति है कि माध्यमिक आदेश क्या पाश चलाने के लिए या पर विफल करने का फैसला करता है; यह केवल तभी होता है जब कोई आदेश नहीं होता है कि कमांड प्रतिस्थापन के मौजूद होने पर कमांड की निकास स्थिति को ही माना जाता है।
चार्ल्स डफी

$commandया तो एक महान प्लेसहोल्डर नहीं है - आदेशों को संग्रहीत करने के लिए स्ट्रिंग्स का उपयोग करने पर BashFAQ # 50 देखें क्योंकि यह अविश्वसनीय रूप से अविश्वसनीय है। फिर भी, यह इससे बेहतर था; डाउनवोट पीछे हट गया।
चार्ल्स डफी

3
while [ -n $(passwd) ]; do
        echo "Try again";
done;

3
यह ऐसा करने का तरीका नहीं है ... आप psswd के stdout को नकार रहे हैं और फिर उस पर एक परीक्षण कर रहे हैं। @ डकवर्थ अच्छा है।
रे फॉस

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