बैश में फ़ंक्शन तर्क के रूप में रिक्त स्थान के साथ एक स्ट्रिंग पास करना


173

मैं एक bash स्क्रिप्ट लिख रहा हूँ जहाँ मुझे अपनी bash स्क्रिप्ट में एक स्ट्रिंग को एक फंक्शन वाली जगह से गुजरने की ज़रूरत है।

उदाहरण के लिए:

#!/bin/bash

myFunction
{
    echo $1
    echo $2
    echo $3
}

myFunction "firstString" "second string with spaces" "thirdString"

जब रन होता है, तो मुझे उम्मीद होती है कि आउटपुट:

firstString
second string with spaces
thirdString

हालाँकि, वास्तव में आउटपुट क्या है:

firstString
second
string

क्या बैश में फ़ंक्शन के लिए एकल तर्क के रूप में रिक्त स्थान के साथ एक स्ट्रिंग पास करने का एक तरीका है?


मेरे लिए काम करता है ... मैं "फ़ंक्शन bla () {echo $ 1;}" फ़ंक्शन के लिए पूर्ण सिंटैक्स का उपयोग करता हूं, एक लाइनर में एक छोटा नहीं कर सकता। यकीन नहीं होता इससे फर्क पड़ता है। बैश का क्या संस्करण?
यूजीन

8
कोशिश echo "$@"या for i in "$@"; do echo $i ; doneसही ढंग से उद्धृत पैरामीटर रिक्त स्थान युक्त प्रयोग करने के लिए। यह अनुभाग के bashतहत सभी प्रलेखन में बहुत स्पष्ट रूप से उल्लिखित है positional parameters
सामवेन

1
मुझे एक समान समस्या थी, एक उद्धृत स्ट्रिंग को एक पैरामीटर के रूप में पारित करने की कोशिश करना और केवल स्ट्रिंग के पहले शब्द को पैरामीटर के भाग के रूप में मान्यता दी जा रही थी। मेरे लिए $ 1 से $ @ में काम करने का समवन का सुझाव। ध्यान दें कि मैं केवल फ़ंक्शन के लिए एक पैरामीटर पास कर रहा था, लेकिन अगर मैं स्टेटमेंट का उपयोग करके अधिक पास कर रहा हूं तो यह आवश्यक होगा।
एरिन गेयर


1
कोशिश myFunction "$@"
vimjet

जवाबों:


176

आपको उद्धरण देना चाहिए और यह भी कि, आपकी फ़ंक्शन घोषणा गलत है।

myFunction()
{
    echo "$1"
    echo "$2"
    echo "$3"
}

और दूसरों की तरह, यह मेरे लिए भी काम करता है। हमें बताएं कि आप किस शेल का उपयोग कर रहे हैं।


3
यह मेरे लिए भी बहुत अच्छा काम करता है। अगर हम myFunction के अंदर कोई अन्य फ़ंक्शन कॉल कर रहे हैं, तो उद्धरण के साथ तर्क पास करें। चीयर्स :)
मिन्हास 23

2
क्या आप बता सकते हैं कि उद्धरणों की आवश्यकता क्यों है? मैंने दोनों के साथ और बिना कोशिश की, और यह मेरे लिए काम नहीं किया। मैं Ubuntu 14.04, GNU बैश, संस्करण 4.3.11 (1) -release (x86_64-pc-linux-gnu) का उपयोग कर रहा हूं। मेरे लिए क्या काम करता है $ @ का उपयोग कर रहा है (उद्धरण के साथ या बिना)।
काइल बेकर

@KyleBaker, बिना उद्धरणों के, $@केवल अनुत्तरित की तरह व्यवहार करता है $*- परिणाम स्ट्रिंग-विभाजित होते हैं और फिर व्यक्तिगत रूप से ग्लोब-विस्तारित होते हैं, इसलिए यदि आपके पास टैब हैं तो वे रिक्त स्थान में परिवर्तित हो जाएंगे, यदि आपके पास ऐसे शब्द हैं जिन्हें ग्लोब के रूप में मूल्यांकन किया जा सकता है होगा, आदि
चार्ल्स डफी

17

उपरोक्त समस्या का एक अन्य समाधान प्रत्येक स्ट्रिंग को एक चर में सेट करना है, फ़ंक्शन को एक शाब्दिक डॉलर के संकेत द्वारा दर्शाए गए चर के साथ कॉल करें \$। फिर फ़ंक्शन evalमें वैरिएबल और आउटपुट को अपेक्षित रूप से पढ़ने के लिए उपयोग करें।

#!/usr/bin/ksh

myFunction()
{
  eval string1="$1"
  eval string2="$2"
  eval string3="$3"

  echo "string1 = ${string1}"
  echo "string2 = ${string2}"
  echo "string3 = ${string3}"
}

var1="firstString"
var2="second string with spaces"
var3="thirdString"

myFunction "\${var1}" "\${var2}" "\${var3}"

exit 0

आउटपुट तब है:

    string1 = firstString
    string2 = second string with spaces
    string3 = thirdString

इसी तरह की समस्या को हल करने की कोशिश में, मैं UNIX के मुद्दे पर सोच रहा था कि मेरे चर अंतरिक्ष में परिमित थे। मैं एक फ़ंक्शन awkबनाने के लिए बाद में एक रिपोर्ट बनाने के लिए उपयोग किए जाने वाले चर की एक श्रृंखला का उपयोग करके एक फ़ंक्शन को एक पाइप सीमांकित स्ट्रिंग को पारित करने की कोशिश कर रहा था । मैंने शुरुआत में ghostdog74 द्वारा पोस्ट किए गए समाधान की कोशिश की, लेकिन इसे काम करने के लिए नहीं मिला क्योंकि मेरे सभी मापदंडों को उद्धरणों में पारित नहीं किया गया था। प्रत्येक पैरामीटर में डबल-कोट जोड़ने के बाद यह तब अपेक्षित रूप से कार्य करना शुरू कर देता है।

नीचे मेरे कोड से पहले की स्थिति है और राज्य के बाद पूरी तरह से काम कर रहा है।

इससे पहले - नॉन फंक्शनिंग कोड

#!/usr/bin/ksh

#*******************************************************************************
# Setup Function To Extract Each Field For The Error Report
#*******************************************************************************
getField(){
  detailedString="$1"
  fieldNumber=$2

  # Retrieves Column ${fieldNumber} From The Pipe Delimited ${detailedString} 
  #   And Strips Leading And Trailing Spaces
  echo ${detailedString} | awk -F '|' -v VAR=${fieldNumber} '{ print $VAR }' | sed 's/^[ \t]*//;s/[ \t]*$//'
}

while read LINE
do
  var1="$LINE"

  # Below Does Not Work Since There Are Not Quotes Around The 3
  iputId=$(getField "${var1}" 3)
done<${someFile}

exit 0

के बाद - फंक्शनिंग कोड

#!/usr/bin/ksh

#*******************************************************************************
# Setup Function To Extract Each Field For The Report
#*******************************************************************************
getField(){
  detailedString="$1"
  fieldNumber=$2

  # Retrieves Column ${fieldNumber} From The Pipe Delimited ${detailedString} 
  #   And Strips Leading And Trailing Spaces
  echo ${detailedString} | awk -F '|' -v VAR=${fieldNumber} '{ print $VAR }' | sed 's/^[ \t]*//;s/[ \t]*$//'
}

while read LINE
do
  var1="$LINE"

  # Below Now Works As There Are Quotes Around The 3
  iputId=$(getField "${var1}" "3")
done<${someFile}

exit 0

7

इस समस्या का सबसे सरल समाधान यह है कि आपको \"शेल स्क्रिप्ट चलाते समय अंतरिक्ष से अलग किए गए तर्कों के लिए उपयोग करने की आवश्यकता है :

#!/bin/bash
myFunction() {
  echo $1
  echo $2
  echo $3
}
myFunction "firstString" "\"Hello World\"" "thirdString"

5

MyFunction की आपकी परिभाषा गलत है। यह होना चाहिए:

myFunction()
{
    # same as before
}

या:

function myFunction
{
    # same as before
}

वैसे भी, यह ठीक है और मेरे लिए बैश 3.2.48 पर ठीक काम करता है।


5

मैं 9 साल लेट हूँ लेकिन एक अधिक गतिशील तरीका होगा

function myFunction {
   for i in "$*"; do echo "$i"; done;
}

2
आह महान! यह वही है जो मुझे कई सवालों पर कुछ समय के लिए देखा गया था। धन्यवाद!
प्रोसोइटोस

2

मेरे लिए काम करने वाला सरल उपाय - उद्धृत $ @

Test(){
   set -x
   grep "$@" /etc/hosts
   set +x
}
Test -i "3 rb"
+ grep -i '3 rb' /etc/hosts

मैं वास्तविक grep कमांड (सेट -x के लिए धन्यवाद) को सत्यापित कर सकता था।


-1

उदाहरण के लिए, आपके प्रारंभिक पाठ को स्ट्रिंग प्रकार चर में सेट करने पर आपको इस समस्या का विस्तार हो सकता है:

function status(){    
  if [ $1 != "stopped" ]; then
     artist="ABC";
     track="CDE";
     album="DEF";
     status_message="The current track is $track at $album by $artist";
     echo $status_message;
     read_status $1 "$status_message";
  fi
}

function read_status(){
  if [ $1 != "playing" ]; then
    echo $2
  fi
}

इस स्थिति में यदि आप स्ट्रिंग के रूप में स्टेटस_मेज़ेज वैरिएबल को पास नहीं करते हैं ("" से घिरा हुआ) तो इसे अलग-अलग तर्कों के माउंट में विभाजित किया जाएगा।

"$ चर" : वर्तमान ट्रैक एबीसी द्वारा DEF में CDE है

$ चर : द


ओपी इस्तेमाल किया myFunction "firstString" "second string with spaces" "thirdString"और यह उसके लिए काम नहीं किया। तो आप जो प्रस्ताव करते हैं वह इस प्रश्न पर लागू नहीं होता है।
डबलडाउन

-2

एक ही तरह की समस्या थी और वास्तव में समस्या फ़ंक्शन नहीं थी और न ही फ़ंक्शन कॉल, लेकिन मैंने फ़ंक्शन के लिए तर्क के रूप में क्या पारित किया।

फ़ंक्शन को स्क्रिप्ट के मुख्य भाग से बुलाया गया था - 'मुख्य' - इसलिए मैंने कमांड लाइन से "st1 a b" "st2 c d" "st3 e f" पास किया और इसे myFunction $ * का उपयोग करके फ़ंक्शन को पास किया।

$ * समस्या का कारण बनता है क्योंकि यह वर्णों के एक समूह में फैलता है जिसे व्हाट्सएप को एक सीमांकक के रूप में उपयोग करके फ़ंक्शन को कॉल किया जाएगा।

समाधान को फ़ंक्शन के लिए 'मुख्य' से स्पष्ट तर्क हैंडलिंग में फ़ंक्शन को कॉल को बदलना था: कॉल तब myFunction "$ 1" "$ 2" "$ 3" होगा जो उद्धरण के रूप में स्ट्रिंग के अंदर व्हाट्सएप को संरक्षित करेगा। तर्क ... इसलिए यदि किसी पैरामीटर में रिक्त स्थान हो सकते हैं, तो इसे फ़ंक्शन के सभी कॉलों में स्पष्ट रूप से नियंत्रित किया जाना चाहिए।

के रूप में यह समस्याओं के लिए लंबी खोजों का कारण हो सकता है, यह तर्क पारित करने के लिए $ * का उपयोग करने के लिए बुद्धिमान कभी नहीं हो सकता है ...

आशा है कि यह किसी दिन मदद करता है, कहीं ... जन।


सही जवाब है "$@"नहीं सभी उद्धृत "$1", "$2"... स्थितीय पैरामीटर है और न ही $*
सैमवेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.