कैसे करें "अगर सही स्थिति नहीं"?


317

echoजब cat /etc/passwd | grep "sysa"सच नहीं है तो मुझे आज्ञा दी जाएगी ।

मैं क्या गलत कर रहा हूं?

if ! [ $(cat /etc/passwd | grep "sysa") ]; then
        echo "ERROR - The user sysa could not be looked up"
        exit 2
fi

7
क्या !कोष्ठक के अंदर नहीं होना चाहिए ? यानी[ ! EXPR ]
acraig5075

7
@ acraig5075 यह किसी भी तरह से मान्य है, लेकिन इस कथन में एक परीक्षण कमांड (जो कि कोष्ठक क्या है) की कोई आवश्यकता नहीं है।
चार्ल्स डफी

जवाबों:


454

प्रयत्न

if ! grep -q sysa /etc/passwd ; then

greptrueयदि यह खोज लक्ष्य पाता है, और falseयदि ऐसा नहीं करता है तो रिटर्न ।

तो false== नहीं true

if गोले का मूल्यांकन बहुत ही लचीले ढंग से किया जाता है, और कई बार कमांड की श्रृंखलाओं की आवश्यकता नहीं होती है (जैसा कि आपने लिखा है)।

इसके अलावा, अपने कोड को देखने के रूप में, $( ... )cmd- प्रतिस्थापन के रूप में आपके उपयोग की प्रशंसा की जानी है, लेकिन इस बारे में सोचें कि प्रक्रिया से क्या निकल रहा है। echo $(cat /etc/passwd | grep "sysa")मेरा मतलब देखने की कोशिश करो । आप आगे -c(गिनती) विकल्प को grep का उपयोग करके ले सकते हैं और फिर वह कर सकते हैं if ! [ $(grep -c "sysa" /etc/passwd) -eq 0 ] ; thenजो काम करता है, बल्कि पुराना स्कूल है।

लेकिन, आप नवीनतम शेल विशेषताओं (अंकगणितीय मूल्यांकन) का उपयोग कर सकते हैं

if ! (( $(grep -c "sysa" /etc/passwd) == 0 )) ; then ...`

जो आपको सी-लैंग आधारित तुलना ऑपरेटरों का उपयोग करने का लाभ देता है, ==,<,>,>=,<=,%और शायद कुछ अन्य।

इस मामले में, ऑरवेलोफाइल की एक टिप्पणी के अनुसार, अंकगणितीय मूल्यांकन को और भी आगे बढ़ाया जा सकता है, जैसे

if ! (( $(grep -c "sysa" /etc/passwd) )) ; then ....

या

if (( ! $(grep -c "sysa" /etc/passwd) )) ; then ....

अंत में, वहाँ एक पुरस्कार कहा जाता है Useless Use of Cat (UUOC)। :-) कुछ लोग उछल कर नीचे गिरेंगे और रोएंगे! मैं सिर्फ इतना कहूंगा कि grepइसकी cmd- लाइन पर एक फ़ाइल का नाम लिया जा सकता है, इसलिए जब आपके पास नहीं है तो अतिरिक्त प्रक्रियाओं और पाइप निर्माणों को क्यों आमंत्रित करें? ;-)

आशा है कि ये आपकी मदद करेगा।


1
यह सब वास्तव में मूर्खतापूर्ण है, मेरे जवाब से बहुत कठिन (प्रश्न) [ stackoverflow.com/a/30400327/912236] grep "^$user:" /etc/passwd को खोजने के लिए अधिक सही तरीका होगा / etc / passwd को आकस्मिक रूप से - grep -vजहां -v खोज खोज करता है यदि आप चाहते थे की गंदगी से बचने के लिए ||
ऑरवेलोफाइल

1
हाँ, अच्छी तरह से एक समस्या को सबसे कुशलता से हल कर रहा है, और फिर विशिष्ट प्रश्न का उत्तर दे रहा है। मैंने विशिष्ट प्रश्न का उत्तर देने की कोशिश की है। आपके विचारों के लिए धन्यवाद। सभी को सफलता मिले।
शेल्टर

1
अपने जवाब पर नहीं उठा, उन्हें काफी मज़ा आया। मैं बस के माध्यम से मैं उपयोगकर्ता नाम पर एक ठीक से बंधे हुए चेक में फेंक दूंगा, अन्यथा अगर ओपी वास्तव में "सीस" या सोमेसुच पर खोज करता है, तो उसे काफी आश्चर्य मिलेगा। सड़क के लिए एक और? (( $( cat file | grep regex | wc -l ) ? 0 : 1 ))
Orwellophile

1
महान! किसी कारण से reqular "! Grep -qs ..." के साथ काम नहीं किया / proc / mounts और यह पता लगाने की कोशिश कर रहा है कि क्या नियमित रूप से छोड़ने वाली यूएसबी-डिस्क को रास्पियन 4.9 कर्नेल पर रखा गया था। यह एक काम पूरी तरह से किया!
DocWeird

33

मुझे लगता है कि इसे सरल बनाया जा सकता है:

grep sysa /etc/passwd || {
    echo "ERROR - The user sysa could not be looked up"
    exit 2
}

या एक कमांड लाइन में

$ grep sysa /etc/passwd || { echo "ERROR - The user sysa could not be looked up"; exit 2; }


4
अच्छा है, लेकिन मैं श्री शेल्टर जवाब पसंद करता हूं क्योंकि "स्व दस्तावेज" है, प्रोग्रामर का इरादा अधिक "पठनीय" है।
0zkr PM

1
मुझे यह संस्करण पसंद है। प्रिंट करने के लिए 1>&2अपने अंत में जोड़ने के बारे में क्या ? echostderr
जुलिएन

2
@ 0zkrPM लेकिन शेल्टर संस्करण बॉर्न शेल में काम नहीं करता है। आप मिल जाएगा!: not found
ceving

1
'grepइस तरह का उपयोग करते समय आउटपुट पुनर्निर्देशन से बचें । -qउत्पादन को दबा देता है।
tbc0

8

मैं क्या गलत कर रहा हूं?

$(...)मान रखता है , निकास की स्थिति नहीं, यही कारण है कि यह दृष्टिकोण गलत है। हालांकि, इस विशिष्ट मामले में, यह वास्तव में काम करता है क्योंकि sysaमुद्रित किया जाएगा जो परीक्षण के बयान को सच बनाता है। हालाँकि, if ! [ $(true) ]; then echo false; fiहमेशा प्रिंट होगा falseक्योंकि trueकमांड stdout को कुछ भी नहीं लिखता (भले ही निकास कोड 0 है)। इसीलिए इसे फिर से परिभाषित करने की आवश्यकता है if ! grep ...; then

एक विकल्प होगा cat /etc/passwd | grep "sysa" || echo error। संपादित करें: एलेक्स के रूप में बताया, बिल्ली यहाँ बेकार है : grep "sysa" /etc/passwd || echo error

भ्रामक होने के बजाय अन्य उत्तर मिले, आशा है कि इससे किसी को मदद मिलेगी।


1

यूनिक्स सिस्टम पर जो इसका समर्थन करता है (ऐसा लगता है कि macOS नहीं):

if getent passwd "$username" >/dev/null; then
    printf 'User %s exists\n' "$username"
else
    printf 'User %s does not exist\n' "$username"
fi 

इसका यह लाभ है कि यह किसी भी निर्देशिका सेवा का उपयोग करेगा जो (YP / NIS या LDAP आदि) और स्थानीय डेटाबेस डेटाबेस फ़ाइल में हो सकती है।


इसके साथ मुद्दा grep -q "$username" /etc/passwdयह है कि यह एक गलत पॉजिटिव देगा जब ऐसा कोई उपयोगकर्ता नहीं है, लेकिन कुछ और पैटर्न से मेल खाता है। यह तब हो सकता है जब फ़ाइल में कहीं और आंशिक या सटीक मिलान हो।

उदाहरण के लिए, मेरी passwdफाइल में, एक लाइन है

build:*:21:21:base and xenocara build:/var/empty:/bin/ksh

यह चीजों caraऔर चीजों पर एक वैध मैच को उकसाएगा enoc, भले ही मेरे सिस्टम पर ऐसे उपयोगकर्ता नहीं हैं।

एक के लिए grepसमाधान सही होने के लिए, आप ठीक ढंग से पार्स करने के लिए की आवश्यकता होगी /etc/passwdफ़ाइल:

if cut -d ':' -f 1 /etc/passwd | grep -qxF "$username"; then
    # found
else
    # not found
fi

... या किसी अन्य इसी तरह के परीक्षण के खिलाफ :-delilized क्षेत्रों के पहले ।


@SDsolar आपका कोड संभवतः bashउस स्थिति में निष्पादित नहीं होता है।
कुसलानंद

1

यहाँ उदाहरण के माध्यम से एक जवाब है:

यह सुनिश्चित करने के लिए कि डेटा लॉगर्स ऑनलाइन हैं एक cronस्क्रिप्ट हर 15 मिनट में चलती है जो इस तरह दिखती है:

#!/bin/bash
#
if ! ping -c 1 SOLAR &>/dev/null
then
  echo "SUBJECT:  SOLAR is not responding to ping" | ssmtp abc@def.com
  echo "SOLAR is not responding to ping" | ssmtp 4151112222@txt.att.com
else
  echo "SOLAR is up"
fi
#
if ! ping -c 1 OUTSIDE &>/dev/null
then
  echo "SUBJECT:  OUTSIDE is not responding to ping" | ssmtp abc@def.com
  echo "OUTSIDE is not responding to ping" | ssmtp 4151112222@txt.att.com
else
  echo "OUTSIDE is up"
fi
#

... और इतने पर प्रत्येक डेटा लकड़हारा है कि आप http://www.SDsolarBlog.com/montage में असेंबल में देख सकते हैं


FYI करें, &>/dev/nullकमांड से सभी आउटपुट को रीडायरेक्ट करता है, त्रुटियों सहित, को/dev/null

(केवल सशर्त को आदेश exit statusकी आवश्यकता है ping)

FYI करें, ध्यान दें कि चूंकि cronनौकरियां चलती हैं, rootइसलिए स्क्रिप्ट sudo pingमें उपयोग करने की कोई आवश्यकता नहीं है cron

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