ব্যাশে ফাংশন আর্গুমেন্ট হিসাবে স্পেসগুলির সাথে একটি স্ট্রিং পাস করা


173

আমি একটি বাশ স্ক্রিপ্ট লিখছি যেখানে আমার বাশ স্ক্রিপ্টের কোনও ফাংশনে স্পেস সহ স্ট্রিংটি পাস করতে হবে।

উদাহরণ স্বরূপ:

#!/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

ব্যাশের কোনও ক্রিয়াকলাপের একক যুক্তি হিসাবে ফাঁকা জায়গায় কোনও স্ট্রিং পাস করার কোনও উপায় আছে কি?


আমার জন্য কাজ করে ... আমি ফাংশনগুলির জন্য সম্পূর্ণ সিনট্যাক্স ব্যবহার করি যদিও "ফাংশন ব্লে () {প্রতিধ্বনি $ 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
এটি আমার জন্য খুব ভাল কাজ করে। যদি আমরা আমার ফাংশনের ভিতরে অন্য ফাংশনটি কল করি তবে উদ্ধৃতি সহ আর্গুমেন্টগুলি পাস করুন। চিয়ার্স :)
minhas23

2
একজনকে উদ্ধৃতি কেন দরকার তা আপনি ব্যাখ্যা করতে পারেন? আমি সাথে এবং বাইরে উভয় চেষ্টা করেছিলাম এবং এটি আমার পক্ষে কার্যকর হয়নি। আমি উবুন্টু 14.04, জিএনইউ ব্যাশ, সংস্করণ 4.3.11 (1) -রিলেজ (x86_64-pc-linux-gnu) ব্যবহার করছি। আমার জন্য কী কাজ করে তা হ'ল (@ (উক্তি সহ বা ছাড়াই) ব্যবহার করছে।
কাইল বেকার

@ কাইলবেকার, উদ্ধৃতিগুলি ছাড়াই, $@অব্যবহৃতদের মতোই আচরণ করে $*- ফলাফলগুলি স্ট্রিং-বিভক্ত হয় এবং তারপরে স্বতন্ত্রভাবে গ্লোব-প্রসারিত হয়, তাই আপনার যদি ট্যাব থাকে তবে সেগুলি স্পেসে রূপান্তরিত হবে, যদি আপনার এমন শব্দ থাকে যা গ্লোব এক্সপ্রেশন হিসাবে মূল্যায়ন করতে পারে তারা ইত্যাদি হবে
চার্লস ডাফি

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

এটির অনুরূপ সমস্যা সমাধানের চেষ্টা করার জন্য, আমি ইউনিক্সের বিষয়টি নিয়ে ভাবছিলাম যে আমার ভেরিয়েবলগুলি স্থান পরিবর্তন করে। আমি awkপরে রিপোর্ট তৈরির জন্য ব্যবহৃত ভেরিয়েবলগুলির একটি সিরিজ সেট করে একটি ফাংশনে পাইপ ডিলিমিট স্ট্রিংটি পাস করার চেষ্টা করছিলাম । আমি গোস্টডোগ 74৪ দ্বারা পোস্ট করা সমাধানটি প্রথমে চেষ্টা করেছিলাম কিন্তু আমার সমস্ত পরামিতি উদ্ধৃতিতে পাস না হওয়ায় এটি কাজ করতে পারেনি। প্রতিটি প্যারামিটারে ডাবল-কোট যুক্ত করার পরে এটি প্রত্যাশা অনুযায়ী কাজ করা শুরু করে।

নীচে আমার কোডের রাষ্ট্রের আগে এবং রাষ্ট্রের পরে সম্পূর্ণরূপে কার্যকারী রয়েছে।

পূর্বে - নন ফাংশন কোড

#!/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()
{
    # same as before
}

বা:

function myFunction
{
    # same as before
}

যাইহোক, এটি দুর্দান্ত দেখায় এবং আমার পক্ষে বাশ 3.2.48 এ কাজ করে।


5

আমি 9 বছর দেরী করছি তবে আরও গতিশীল উপায় হবে

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

2
আহ! এটাই হ'ল অনেক প্রশ্নের জন্য আমাকে কিছু সময়ের জন্য অনুসন্ধান করা হয়েছিল। ধন্যবাদ!
prosoitos

2

সহজ সমাধান যা আমার পক্ষে কাজ করেছে - উদ্ধৃত $ @

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

আমি প্রকৃত গ্রেপ কমান্ডটি (সেট-এক্সকে ধন্যবাদ) যাচাই করতে পারি।


-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 এ সিডিই হয়

$ পরিবর্তনশীল : দ্য


ওপি ব্যবহার করেছে myFunction "firstString" "second string with spaces" "thirdString"এবং এটি তার পক্ষে কার্যকর হয়নি। সুতরাং আপনি যা প্রস্তাব করেন তা এই প্রশ্নের ক্ষেত্রে প্রযোজ্য না।
ডাবলডাউন

-2

একই ধরণের সমস্যা ছিল এবং আসলে সমস্যাটি ফাংশন বা ফাংশন কল ছিল না, তবে আমি ফাংশনে যুক্তি হিসাবে যা পাস করেছি।

ফাংশনটি স্ক্রিপ্টের মূল অংশ থেকে ডেকে আনা হয়েছিল - 'প্রধান' - সুতরাং আমি কমান্ড লাইন থেকে "st1 a b" "st2 c d" "st3 e f" পেরিয়ে আমার ফাংশন $ * ব্যবহার করে ফাংশনে পৌঁছে দিয়েছি

$ * সমস্যার কারণ হিসাবে এটি অক্ষরের একটি সেটে প্রসারিত হয় যা ডাইমেটার হিসাবে সাদা অংশ ব্যবহার করে ফাংশনে ডাকে ব্যাখ্যা করা হবে।

সমাধানটি ছিল 'ফাংশন'র দিকে' মেইন 'থেকে স্পষ্ট যুক্তিতে হ্যান্ডলিং করে ফাংশনে কলটি পরিবর্তন করা: কলটি তখন আমার ফাংশন হবে "$ 1" "$ 2" "$ 3" যা স্ট্রসের অভ্যন্তরে সাদা স্থানকে সংরক্ষণ করবে যেহেতু উদ্ধৃতিগুলি সীমিত করে দেবে তর্কগুলি ... সুতরাং যদি কোনও প্যারামিটারে স্পেস থাকতে পারে তবে তা সমস্ত ফাংশনগুলির কলগুলিতে স্পষ্টভাবে পরিচালনা করা উচিত।

যেহেতু সমস্যাগুলির দীর্ঘ অনুসন্ধানের কারণ এটি হতে পারে, যুক্তিগুলি পাস করার জন্য $ * ব্যবহার করা কখনই বুদ্ধিমানের কাজ হতে পারে ...

আশা করি এটি কাউকে সাহায্য করবে, একদিন, কোথাও ... জানু।


সঠিক উত্তর হল "$@"না সব উদ্ধৃত, "$1", "$2", ... অবস্থানগত paramters না $*
সামভিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.