शेल स्क्रिप्टिंग में लॉजिकल या ऑपरेशन कैसे करें


571

मैं एक साधारण स्थिति की जांच करने की कोशिश कर रहा हूं, लेकिन यह काम नहीं करता है।

यदि $#के बराबर है 0या इससे अधिक है 1तो नमस्ते कहो।

मैंने निम्नलिखित सिंटैक्स को बिना किसी सफलता के आज़माया है:

if [ "$#" == 0 -o "$#" > 1 ] ; then
 echo "hello"
fi

if [ "$#" == 0 ] || [ "$#" > 1 ] ; then
 echo "hello"
fi

वे दोनों मेरे लिए काम करते हैं। क्या आपने शेलबैंग लाइन में एक शेल निर्दिष्ट किया था?
जेसन मैककेरी 2

1
@ जेसन मैं वास्तव में शेबंग लाइन भूल गया था, लेकिन मैंने इसे अभी-अभी इसके साथ परीक्षण किया और यह काम नहीं किया।
स्ट्रॉबेरी

25
>श / बैश में आउटपुट पुनर्निर्देशन है। अब आपके पास संभवतः एक फ़ाइल है जिसका नाम है 1
मार्क 4o

बैश तुलना के बारे में जानकारी के लिए, कृपया मेरे पिछले सवालों के जवाब यहां और यहां देखें । ब्रैकेट, डबल ब्रैकेट और डबल कोष्ठक के संबंध में अतिरिक्त जानकारी के लिए, मेरा जवाब यहां देखें
अगली सूचना तक रोक दिया गया।

यह काम नहीं करता है क्योंकि आप कम्पास को गलत मानते हैं: "$ #" == "0" या $ #
-एक

जवाबों:


987

यह काम करना चाहिए:

#!/bin/bash

if [ "$#" -eq 0 ] || [ "$#" -gt 1 ] ; then
    echo "hello"
fi

मुझे यकीन नहीं है कि यह अन्य गोले में अलग है, लेकिन यदि आप <,> का उपयोग करना चाहते हैं, तो आपको उन्हें डबल कोष्ठक के अंदर डालने की आवश्यकता है जैसे:

if (("$#" > 1))
 ...

2
मुझे यकीन नहीं है कि अगर यह एक और शेल में अलग है, लेकिन बैश में, यदि आप उपयोग करना चाहते हैं> या <, तो आपको उन्हें डबल कोष्ठक में डालना होगा जैसे: (("$ a" <"$ b"))
कोडिंग

1
@ डग: ऐसा नहीं है कि यूनिक्स उनका उपयोग नहीं करता है, यह बैश है और मुझे पता है कि सभी अन्य गोले इनपुट / आउटपुट पुनर्निर्देशन के लिए उपयोग करते हैं।
कास्केबेल

56

यह कोड मेरे लिए काम करता है:

#!/bin/sh

argc=$#
echo $argc
if [ $argc -eq 0 -o $argc -eq 1 ]; then
  echo "foo"
else
  echo "bar"
fi

मुझे नहीं लगता कि sh "==" का समर्थन करता है। तार की तुलना करने के लिए "=" का प्रयोग करें और -ts की तुलना करने के लिए -eq करें।

man test

अधिक जानकारी के लिए।


से अधिक के लिए विकल्प क्या है? तिह के लिए आधिकारिक दस्तावेज कहां है?
स्ट्रॉबेरी

3
-gtसे अधिक के लिए होना चाहिए । या बस इसे सभी के साथ बदलें [ $# -ne 1 ]
mark4o

की तुलना में अधिक से अधिक है, मेरा जवाब देखें। आधिकारिक दस्तावेज मैन टेस्ट में है क्योंकि जम्मनट ने बताया है।
कोडिंग डिस्ट्रिक्ट

बस अपने शेल के आधार पर, दूसरों के लिए एक फ़िजी के रूप में, सबसे अधिक समर्थन == (अब एक दिन) तुलना ऑपरेटर के रूप में, हालांकि अधिकांश समय यह = ऑपरेटर के रूप में ही होता है। मुझे लगता है कि यदि आप तुलना के लिए -gt और -ne का उपयोग कर रहे हैं, तो बेहतर होगा कि आप अपनी स्क्रिप्टिंग शैली को बनाए रखने के लिए == या = का उपयोग करें। हैप्पी
बशिंग

34

यदि आप bash एक्जिट कोड स्टेटस $ का उपयोग कर रहे हैं ? चर के रूप में, यह करना बेहतर है:

if [ $? -eq 4 -o $? -eq 8 ] ; then  
   echo "..."
fi

क्योंकि अगर तुम करते हो:

if [ $? -eq 4 ] || [ $? -eq 8 ] ; then  

OR का बायां हिस्सा $ को बदल देता है ? चर, इसलिए OR के दाहिने भाग में मूल $ नहीं है ? मूल्य।


2
$ # स्क्रिप्ट में पास किए गए तर्कों की संख्या लौटाता है। सही उपयोग की जाँच के लिए उपयोगी। ऐसा नहीं लगता कि पूछने वाला एक्ज़िट कोड का उपयोग कर रहा है।
सेंटीमैन

27

कभी-कभी आपको डबल ब्रैकेट का उपयोग करने की आवश्यकता होती है, अन्यथा आपको बहुत सारे तर्कों की तरह त्रुटि मिलती है

if [[ $OUTMERGE == *"fatal"* ]] || [[ $OUTMERGE == *"Aborting"* ]]
  then
fi

1
यह उपयोगी है क्योंकि यह यहाँ केवल एक चीज है जो मुझे गैर-पूर्णांक तुलनाओं का एक उदाहरण दिखाती है, जो वाक्य रचना में थोड़ा अलग है।
क्रिस्टोफर हंटर


7

क्या आपने कुछ इस तरह की कोशिश की है:

if [ $# -eq 0 ] || [ $# -gt 1 ] 
then
 echo "$#"
fi

हाँ मेरे पास है। यह echoतब भी नमस्कार है जब मेरे पास एक भी तर्क हो।
स्ट्रॉबेरी

दूसरा $#पहले टेस्ट का रिटर्न वैल्यू हो सकता है?
किस्मतडॉनल्ड

5

से बैश संदर्भ मैनुअल → 3.4.2 विशेष पैरामीटर

#
($ #) दशमलव में स्थितीय मापदंडों की संख्या का विस्तार करता है।

इसलिए, $#हमेशा 0 या एक बड़ा पूर्णांक होगा।

इसलिए यदि आप कुछ करना चाहते हैं जब $#भी 0 या 1 से बड़ा हो, तो आपको बस यह देखना होगा $#कि क्या है या नहीं 1:

[ $# -eq 1 ] && echo "1 positional param" || echo "0 or more than 1"

यह सिंटैक्स का उपयोग करता है:

[ condition ] && {things if true} || {things if false}

बाश में आप कुछ इस तरह कर सकते हैं:[[ -n $A ]] && echo 1 || echo 2
premek.v

@ premek.v टिप्पणी के लिए धन्यवाद। मेरा जवाब बहुत बुरी तरह से समझाया गया था, मैंने सिर्फ इस उम्मीद में इसे संपादित किया कि यह विषय पर अधिक प्रकाश डाले।
फेडोरक्वी 'एसओ ने'

1

और बैश में

 line1=`tail -3 /opt/Scripts/wowzaDataSync.log | grep "AmazonHttpClient" | head -1`
 vpid=`ps -ef|  grep wowzaDataSync | grep -v grep  | awk '{print $2}'`
 echo "-------->"${line1}
    if [ -z $line1 ] && [ ! -z $vpid ]
    then
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Process Is Working Fine"
    else
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Prcess Hanging Due To Exception With PID :"${pid}
   fi

या बैश में

line1=`tail -3 /opt/Scripts/wowzaDataSync.log | grep "AmazonHttpClient" | head -1`
vpid=`ps -ef|  grep wowzaDataSync | grep -v grep  | awk '{print $2}'`
echo "-------->"${line1}
   if [ -z $line1 ] || [ ! -z $vpid ]
    then
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Process Is Working Fine"
    else
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Prcess Hanging Due To Exception With PID :"${pid}
  fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.