कैसे एक बैश स्क्रिप्ट लिखने के लिए जो वैकल्पिक इनपुट तर्क लेता है?


471

मैं चाहता हूं कि मेरी स्क्रिप्ट एक वैकल्पिक इनपुट लेने में सक्षम हो,

उदाहरण के लिए वर्तमान में मेरी स्क्रिप्ट है

#!/bin/bash
somecommand foo

लेकिन मैं यह कहना चाहूंगा:

#!/bin/bash
somecommand  [ if $1 exists, $1, else, foo ]

3
बैश या POSIX? बैश के साथ, अधिक संभावनाएं हैं
user123444555621

@ Pumbaa80 बैश - मैंने टैग अपडेट किए हैं।
अबे


जवाबों:


705

आप डिफ़ॉल्ट-मूल्य सिंटैक्स का उपयोग कर सकते हैं:

somecommand ${1:-foo}

उपरोक्त संदर्भ , जैसा कि बैश संदर्भ मैनुअल में वर्णित है - 3.5.3 शेल पैरामीटर विस्तार [जोर मेरा]:

यदि पैरामीटर अशांत या अशक्त है , तो शब्द का विस्तार प्रतिस्थापित किया जाता है। अन्यथा, पैरामीटर का मान प्रतिस्थापित किया जाता है।

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

somecommand ${1-foo}

बैश संदर्भ मैनुअल से फिर से - 3.5.3 शेल पैरामीटर विस्तार :

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


52
कृपया उपरोक्त कमांड के बीच शब्दार्थ अंतर पर ध्यान दें, "वापसी fooअगर $1कोई परेशान है या एक खाली स्ट्रिंग है ", और ${1-foo}, "वापसी fooअगर $1परेशान है"।
l0b0

12
क्या आप बता सकते हैं कि यह क्यों काम करता है? विशेष रूप से, ':' और '-' का कार्य / उद्देश्य क्या है?
jwien001

8
@ jwein001: ऊपर दिए गए उत्तर में, चर का अपरिभाषित होने पर एक डिफ़ॉल्ट मूल्य को वापस करने के लिए एक प्रतिस्थापन ऑपरेटर का उपयोग किया जाता है। विशेष रूप से, तर्क यह है कि "यदि $ 1 मौजूद है और अशक्त नहीं है, तो उसका मूल्य लौटाएं; अन्यथा, वापसी फू करें।" बृहदान्त्र वैकल्पिक है। यदि यह छोड़ दिया गया है, तो परिवर्तन "मौजूद है और शून्य नहीं है" केवल "मौजूद है।" माइनस साइन 'फू' के बराबर $ 1 सेट किए बिना फू को वापस करने के लिए निर्दिष्ट करता है। प्रतिस्थापन ऑपरेटर विस्तार ऑपरेटरों के एक उपवर्ग हैं। रॉबिंस और बीबे की की धारा 6.1.2.1 देखें क्लासिक शैल स्क्रिप्टिंग [ओ रेली] ( shop.oreilly.com/product/9780596005955.do )
Jubbles

5
@ बुलबुले या यदि आप एक साधारण संदर्भ के लिए एक पूरी किताब नहीं खरीदना चाहते हैं ... tldp.org/LDP/abs/html/parameter-substitution.html
Ohad Schneider

2
यह उत्तर और भी बेहतर होगा यदि यह दिखाया जाए कि डिफ़ॉल्ट को कमांड चलाने का परिणाम कैसे बनाया जा सकता है, जैसा कि @hagen करता है (हालांकि वह उत्तर असंगत है)।
सैटर्डमैन

309

आप एक चर के लिए एक डिफ़ॉल्ट मान सेट कर सकते हैं जैसे:

somecommand.sh

#!/usr/bin/env bash

ARG1=${1:-foo}
ARG2=${2:-bar}
ARG3=${3:-1}
ARG4=${4:-$(date)}

echo "$ARG1"
echo "$ARG2"
echo "$ARG3"
echo "$ARG4"

यहाँ कुछ उदाहरण दिए गए हैं कि यह कैसे काम करता है:

$ ./somecommand.sh
foo
bar
1
Thu Mar 29 10:03:20 ADT 2018

$ ./somecommand.sh ez
ez
bar
1
Thu Mar 29 10:03:40 ADT 2018

$ ./somecommand.sh able was i
able
was
i
Thu Mar 29 10:03:54 ADT 2018

$ ./somecommand.sh "able was i"
able was i
bar
1
Thu Mar 29 10:04:01 ADT 2018

$ ./somecommand.sh "able was i" super
able was i
super
1
Thu Mar 29 10:04:10 ADT 2018

$ ./somecommand.sh "" "super duper"
foo
super duper
1
Thu Mar 29 10:05:04 ADT 2018

$ ./somecommand.sh "" "super duper" hi you
foo
super duper
hi
you

2
आह अच्छा। -मुझे उलझन में (यह नकार दिया गया है?)।
रफी खाचदौरेन २

5
नहींं - यह सिर्फ एक अजीब तरीका है जो काम कर रहा है। मैं इसे थोड़ा स्पष्ट करने के लिए कुछ और उदाहरण जोड़ूंगा ... धन्यवाद!
ब्रैड पार्क्स

44
if [ ! -z $1 ] 
then 
    : # $1 was given
else
    : # $1 was not given
fi

1
तकनीकी रूप से, यदि आप एक खाली स्ट्रिंग में गुजरते हैं '' जो एक पैरामीटर के रूप में गिना जा सकता है, लेकिन आपका चेक इसे याद करेगा। उस स्थिति में $ # कहेंगे कि कितने मापदंडों को दिया गया था
vmpstr

18
-nके रूप में ही है ! -z
l0b0

मुझे अलग-अलग परिणाम मिलते हैं -nऔर ! -zइसलिए मैं कहूंगा कि यहां ऐसा नहीं है।
एलिएजर

क्योंकि आप चर को उद्धृत करने में विफल रहे, [ -n $1 ] हमेशा सत्य रहेगा । यदि आप बैश का उपयोग [[ -n $1 ]]करते हैं , तो आप अपेक्षा के अनुसार व्यवहार करेंगे, अन्यथा आपको उद्धृत करना होगा[ -n "$1" ]
ग्लेन जैकमैन

21

आप के साथ तर्कों की संख्या की जांच कर सकते हैं $#

#!/bin/bash
if [ $# -ge 1 ]
then
    $1
else
    foo
fi

10

कृपया मत भूलना, अगर इसके चर $ 1 .. $ n आपको प्रतिस्थापन का उपयोग करने के लिए एक नियमित चर को लिखने की आवश्यकता है

#!/bin/bash
NOW=$1
echo  ${NOW:-$(date +"%Y-%m-%d")}

2
ऊपर ब्रैड का उत्तर यह साबित करता है कि तर्क चर भी मध्यवर्ती संस्करण के बिना प्रतिस्थापित किए जा सकते हैं।
वडज़िम

2
एक निश्चित मूल्य के बजाय डिफ़ॉल्ट जैसे कमांड का उपयोग करने का तरीका नोट करने के लिए +1। यह भी संभव है:DAY=${1:-$(date +%F -d "yesterday")}
गैरेन एस

3

वैकल्पिक एकाधिक तर्कों के लिए, lsकमांड के साथ सादृश्य द्वारा जो एक या एक से अधिक फाइलें ले सकता है या डिफ़ॉल्ट रूप से वर्तमान निर्देशिका में सब कुछ सूचीबद्ध कर सकता है:

if [ $# -ge 1 ]
then
    files="$@"
else
    files=*
fi
for f in $files
do
    echo "found $f"
done

पथ में रिक्त स्थान के साथ फ़ाइलों के लिए सही ढंग से काम नहीं करता है, अफसोस। पता नहीं कैसे अभी तक वह काम करने के लिए है।


2

यह वैकल्पिक 1 आर्ग के लिए डिफ़ॉल्ट मान देता है, और कई आर्ग को संरक्षित करता है।

 > cat mosh.sh
   set -- ${1:-xyz} ${@:2:$#} ; echo $*    
 > mosh.sh
   xyz
 > mosh.sh  1 2 3
   1 2 3 

1

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

~$ sh co.sh
2017-01-05

~$ sh co.sh 2017-01-04
2017-01-04

~$ cat co.sh

DAY=${1:-$(date +%F -d "yesterday")}
echo $DAY
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.