बैश शेल स्क्रिप्ट में इनपुट तर्क के अस्तित्व की जाँच करें


1335

मुझे एक इनपुट तर्क के अस्तित्व की जांच करने की आवश्यकता है। मेरे पास निम्न स्क्रिप्ट है

if [ "$1" -gt "-1" ]
  then echo hi
fi

मुझे मिला

[: : integer expression expected

मैं इनपुट तर्क 1 की जांच कैसे करूं कि यह मौजूद है या नहीं?

जवाबों:


2328

यह है:

if [ $# -eq 0 ]
  then
    echo "No arguments supplied"
fi

$#चर आप इनपुट तर्क स्क्रिप्ट पारित किया गया था की संख्या पता चलेगी।

या आप जांच सकते हैं कि कोई तर्क एक रिक्त स्ट्रिंग है या नहीं:

if [ -z "$1" ]
  then
    echo "No argument supplied"
fi

-zयदि "$ 1" के विस्तार के एक रिक्त स्ट्रिंग है या नहीं स्विच परीक्षण किया जाएगा। यदि यह एक अशक्त स्ट्रिंग है तो शरीर को निष्पादित किया जाता है।


62
मैं इसे इस तरह से करना पसंद करता हूं, ट्रिक सिंटैक्स में और फिर भी पॉसिक्स स्वीकार्य। [ -z "$1" ] && echo "No argument supplied" मैं वन-लाइनर्स पसंद करता हूं, क्योंकि वे मेरे लिए आसान हैं; और इसका उपयोग करने की तुलना में निकास मूल्य की जांच करना भी तेज़ हैif
जेएम बेकर

168
आप संभवतः exit 1स्क्रिप्ट को कार्य करने के लिए तर्क की आवश्यकता होने पर ब्लॉक के अंदर अपने इको के अंत में जोड़ना चाहते हैं । स्पष्ट है, लेकिन पूर्णता के लिए ध्यान देने योग्य है।
msanford

16
पहले तर्क के लिए प्रारंभिक लेकिन खाली होने के बावजूद, यह शायद ही कभी उपयोगी है; programname "" secondarg third$#जांच स्पष्ट तर्क की संख्या की जांच करता है।
ट्रिपलआई

39
एक नॉब के लिए, विशेष रूप से कोई व्यक्ति जो एक गैर-स्क्रिप्टिंग पृष्ठभूमि से आता है, इन बातों के बारे में कुछ विशिष्टताओं का उल्लेख करना भी महत्वपूर्ण है। आप यह भी उल्लेख कर सकते हैं कि हमें उद्घाटन और समापन ब्रेस के बाद एक स्थान की आवश्यकता है। अन्यथा चीजें काम नहीं करती हैं। मैं खुद एक स्क्रिप्टिंग नॉब हूं (मैं सी बैकग्राउंड से आती हूं) और इसे कठिन तरीका पाया। यह केवल तभी था जब मैंने पूरी बात को कॉपी करने का फैसला किया "जैसा कि" मेरे लिए चीजें काम करती हैं। यह तब मुझे महसूस हुआ कि मुझे उद्घाटन ब्रेस के बाद और समापन से पहले एक स्थान छोड़ना था।
HighOnMeat

72
और वैकल्पिक args के लिएif [ ! -z "$1" ]; then ...
gcb

346

इस तरह से प्रदर्शन करना बेहतर है

if [[ $# -eq 0 ]] ; then
    echo 'some message'
    exit 1
fi

यदि आपके पास बहुत कम तर्क हैं, तो आपको आमतौर पर बाहर निकलने की आवश्यकता है।


72
नहीं, यह नहीं है: यह वह है exit 1जो आप आमतौर पर चाहते हैं, और [[ ]]परीक्षण का उपयोग करता है जो (iirc) आमतौर पर अधिक उचित होता है। तो लोगों के लिए नेत्रहीन कॉपी-पेस्टिंग कोड यह बेहतर जवाब है।
dshepherd

42
[] और [[]] के बीच अंतर के बारे में अधिक जानने के लिए देखें stackoverflow.com/questions/3427872/…
सेबस्टियन ग्रिग्नोली

103

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

scale=${2:-1}
emulator @$1 -scale $scale

अगर उपयोगकर्ता scale2 पैरामीटर के रूप में पारित नहीं हुआ है , तो मैं -scale 1डिफ़ॉल्ट रूप से एंड्रॉइड एमुलेटर लॉन्च करता हूं । ${varname:-word}एक विस्तार ऑपरेटर है। अन्य विस्तार ऑपरेटर भी हैं:

  • ${varname:=word}जो मान वापस करने के बजाय अपरिभाषित सेट करता है ;varnameword
  • ${varname:?message}जो या तो varnameपरिभाषित करता है और अगर यह परिभाषित नहीं है या वापस नहीं आता है messageऔर स्क्रिप्ट को निरस्त करता है (पहले उदाहरण की तरह);
  • ${varname:+word}जो परिभाषित होने पर wordही वापस आता varnameहै और अशक्त नहीं है; अन्यथा अशक्त।

1
ऊपर दिए गए उदाहरण का उपयोग करने लगता है ${varname?message}। क्या अतिरिक्त :टाइपो है, या क्या यह व्यवहार को बदलता है?
ईकी

6
Eki, ":" इस उदाहरण में / बिन / सच के लिए एक अंतर्निहित कमांड और आशुलिपि है। यह एक कुछ भी नहीं आदेश का प्रतिनिधित्व करता है जो मूल रूप से प्रदान किए गए तर्कों की अनदेखी करता है। इस परीक्षण में यह आवश्यक है कि दुभाषिया को "$ varname" की सामग्री को निष्पादित करने की कोशिश करने से रोका जाए (जो कि आप निश्चित रूप से ऐसा नहीं करना चाहते हैं)। ध्यान देने योग्य भी; आप अपनी इच्छानुसार इस विधि के साथ कई चर का परीक्षण कर सकते हैं। और सभी विशिष्ट त्रुटि संदेशों के साथ। यानी: ${1?"First argument is null"} ${2?"Please provide more than 1 argument"}
user.friendly

48

प्रयत्न:

 #!/bin/bash
 if [ "$#" -eq  "0" ]
   then
     echo "No arguments supplied"
 else
     echo "Hello world"
 fi

4
आपको $#और के लिए दोहरे उद्धरण चिह्नों की आवश्यकता क्यों है 0?
user13107

1
कोई समस्या नहीं अगर हम $ # और 0 के रूप में दोहरे उद्धरण के बिना उपयोग करते हैं
रंजीथकुमार टी

खिड़कियों पर, यह जाने का एकमात्र तरीका है।
लाजोस मेस्सरोस

2
यह उत्तर एक स्क्रिप्ट के लिए शानदार शुरुआत प्रदान करता है जिसे मैंने अभी बनाया है। दिखाने के लिए elseभी धन्यवाद ।
क्रिस के

2
@ उपयोगकर्ता 13107 बैश में दोहरे उद्धृत चर ग्लोबिंग को रोकते हैं (जैसे विस्तार फ़ाइल नाम foo*) और शब्द बंटवारा (यानी यदि सामग्री में व्हाट्सएप हो तो सामग्री को विभाजित करना)। इस मामले में यह उद्धृत करना आवश्यक नहीं है $#क्योंकि यह दोनों मामले लागू नहीं होते हैं। उद्धृत करना 0भी आवश्यक नहीं है, लेकिन कुछ लोग मूल्यों को उद्धृत करना पसंद करते हैं क्योंकि वे वास्तव में तार हैं और इससे यह अधिक स्पष्ट होता है।
डेनिस

39

यह पता लगाने का एक और तरीका है कि क्या स्क्रिप्ट में तर्क पारित किए गए थे:

((!$#)) && echo No arguments supplied!

ध्यान दें कि शेल अरिथमेटिक के(( expr )) नियमों के अनुसार अभिव्यक्ति का मूल्यांकन किया जाता है ।

किसी भी तर्क के अभाव में बाहर निकलने के लिए, कोई भी कह सकता है:

((!$#)) && echo No arguments supplied! && exit 1

ऊपर कहने के लिए एक और (अनुरूप) तरीका होगा:

let $# || echo No arguments supplied

let $# || { echo No arguments supplied; exit 1; }  # Exit if no arguments!

help let कहते हैं:

let: let arg [arg ...]

  Evaluate arithmetic expressions.

  ...

  Exit Status:
  If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.

2
-1 यह सबसे खराब तरीका हो सकता है यदि किसी तर्क के अस्तित्व को मान्य किया जाए .. साथ ही यह इतिहास प्रतिस्थापन को ट्रिगर कर सकता है और संभवतः खराब चीजें कर सकता है।
user.friendly

2
के बजाय exitजो मेरे zsh प्रक्रिया को मारता है, मैं का उपयोग करें returnजो इसे मारने नहीं करता है
टीमो

क्यों ((!$#))इतिहास प्रतिस्थापन ट्रिगर होगा ?
झरो

25

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

#!/bin/bash

if [ -z "$1" ]; then
    echo -e "\nPlease call '$0 <argument>' to run this command!\n"
    exit 1
fi

1
तो, यह आपको केवल एक तर्क की आवश्यकता है?
डेनियल

21

केवल इसलिए कि मुझे इंगित करने के लिए एक और आधार बिंदु है मैं जोड़ूंगा कि आप बस अपने स्ट्रिंग का परीक्षण कर सकते हैं अशक्त है:

if [ "$1" ]; then
  echo yes
else
  echo no
fi

इसी तरह अगर आप उम्मीद कर रहे हैं कि arg काउंट सिर्फ आपके अंतिम परीक्षण का है:

if [ "$3" ]; then
  echo has args correct or not
else
  echo fixme
fi

और इतने पर किसी भी arg या var के साथ


4

यदि आप यह जाँचना चाहते हैं कि क्या तर्क मौजूद है, तो आप जाँच सकते हैं कि क्या तर्कों की संख्या आपके लक्ष्य तर्क संख्या से अधिक या बराबर है।

निम्न स्क्रिप्ट प्रदर्शित करता है कि यह कैसे काम करता है

test.sh

#!/usr/bin/env bash

if [ $# -ge 3 ]
then
  echo script has at least 3 arguments
fi

निम्नलिखित उत्पादन करता है

$ ./test.sh
~
$ ./test.sh 1
~
$ ./test.sh 1 2
~
$ ./test.sh 1 2 3
script has at least 3 arguments
$ ./test.sh 1 2 3 4
script has at least 3 arguments

3

एक छोटा सा बता दें कि बैश में संख्यात्मक परीक्षण ऑपरेटरों केवल पूर्णांकों पर काम ( -eq, -lt,-ge , आदि)

मुझे यह सुनिश्चित करना पसंद है कि मेरी $ वरियाँ इनसर्ट हैं

var=$(( var + 0 ))

इससे पहले कि मैं उनका परीक्षण करूं, बस "[: पूर्णांक arg आवश्यक" त्रुटि के खिलाफ बचाव करें।


1
नीट ट्रिक, लेकिन कृपया ध्यान दें: अंकगणित में फ्लोट को संभालने के लिए बैश की अक्षमता के कारण, यह विधि एक वाक्यविन्यास त्रुटि का कारण बन सकती है और गैर-शून्य वापस कर सकती है जो एक बाधा होगी जहां एरेक्सिट सक्षम है। var=$(printf "%.0f" "$var")एक स्ट्रिंग दी जाने पर गैर-शून्य निकास से फ्लोट को संभाल सकता है लेकिन गैर-शून्य निकास से ग्रस्त है। यदि आपको एक अजीब बात नहीं लगती है, तो इस विधि का उपयोग मैं एक पूर्णांक को लागू करने के लिए सबसे मजबूत लगता है var=$(<<<"$var" awk '{printf "%.0f", $0}'):। यदि var परेशान है, तो यह "0" के लिए डिफॉल्ट करता है। यदि var एक फ्लोट है, तो इसे निकटतम पूर्णांक में गोल किया जाता है। नकारात्मक मान भी उपयोग करने के लिए ठीक हैं।
user.friendly

0

एक लाइनर बैश फ़ंक्शन सत्यापन

myFunction() {

    : ${1?"forgot to supply an argument"}
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

}

फ़ंक्शन का नाम और उपयोग जोड़ें

myFunction() {

    : ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage:  ${FUNCNAME[0]} some_integer"}
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

}

पूर्णांक की जाँच करने के लिए सत्यापन जोड़ें

अतिरिक्त सत्यापन जोड़ने के लिए, उदाहरण के लिए यह देखने के लिए जांच करें कि क्या तर्क एक पूर्णांक है, सत्यापन फ़ंक्शन को कॉल करने के लिए सत्यापन एक लाइनर को संशोधित करें:

: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage:  ${FUNCNAME[0]} some_integer"} && validateIntegers $1 || die "Must supply an integer!"

फिर, एक सत्यापन फ़ंक्शन का निर्माण करें जो तर्क को मान्य करता है, सफलता पर 0 वापस, 1 विफलता पर और एक फ़ंक्शन जो विफलता पर संदेश को निरस्त करता है

validateIntegers() {

    if ! [[ "$1" =~ ^[0-9]+$ ]]; then
        return 1 # failure
    fi
    return 0 #success

}

die() { echo "$*" 1>&2 ; exit 1; }

और भी सरल - बस उपयोग करें set -u

set -u यह सुनिश्चित करता है कि प्रत्येक संदर्भित चर सेट किया जाता है जब इसका उपयोग किया जाता है, इसलिए बस इसे सेट करें और इसे भूल जाएं

myFunction() {
    set -u
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

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