Een string met spaties doorgeven als functieargument in Bash

Ik ben een Bash-script aan het schrijven waarbij ik een string met spaties moet doorgeven aan een functie in mijn Bash-script.

Bijvoorbeeld:

#!/bin/bash
myFunction
{
    echo $1
    echo $2
    echo $3
}
myFunction "firstString" "second string with spaces" "thirdString"

Als het wordt uitgevoerd, is de output die ik zou verwachten:

firstString
second string with spaces
thirdString

Wat echter daadwerkelijk wordt uitgevoerd, is:

firstString
second
string

Is er een manier om een ​​string met spaties als een enkel argument door te geven aan een functie in Bash?


Antwoord 1, autoriteit 100%

Je moet aanhalingstekens toevoegen en ook je functiedeclaratie is verkeerd.

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

En net als de anderen werkt het ook voor mij.


Antwoord 2, autoriteit 13%

Een andere oplossing voor het bovenstaande probleem is om elke string in te stellen op een variabele, de functie aan te roepen met variabelen die worden aangegeven met een letterlijk dollarteken \$. Gebruik vervolgens in de functie evalom de variabele te lezen en uit te voeren zoals verwacht.

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

Uitvoer is dan:

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

Bij het proberen om een ​​soortgelijk probleem op te lossen, kwam ik het probleem van UNIX tegen, omdat ik dacht dat mijn variabelen in de ruimte waren afgebakend. Ik probeerde een door pijpen gescheiden tekenreeks door te geven aan een functie met behulp van awkom een ​​reeks variabelen in te stellen die later werden gebruikt om een ​​rapport te maken. Ik heb aanvankelijk de oplossing geprobeerd die door ghostdog74 was gepost, maar kon het niet laten werken omdat niet al mijn parameters tussen aanhalingstekens werden doorgegeven. Na het toevoegen van dubbele aanhalingstekens aan elke parameter begon het te functioneren zoals verwacht.

Hieronder staat de voor-status van mijn code en volledig functionerende na-status.

Vroeger – Niet-werkende code

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

Na – Functionerende code

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

Antwoord 3, autoriteit 7%

Een meer dynamische manier zou zijn:

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

Antwoord 4, autoriteit 4%

De eenvoudigste oplossing voor dit probleem is dat je gewoon \"moet gebruiken voor door spaties gescheiden argumenten bij het uitvoeren van een shellscript:

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

Antwoord 5, autoriteit 3%

Uw definitie van mijnFunctie is verkeerd. Het zou moeten zijn:

myFunction()
{
    # same as before
}

of:

function myFunction
{
    # same as before
}

Hoe dan ook, het ziet er goed uit en werkt prima voor mij op Bash 3.2.48.


Antwoord 6, autoriteit 2%

Eenvoudige oplossing die voor mij werkte — geciteerd [email protected]

Test(){
   set -x
   grep "[email protected]" /etc/hosts
   set +x
}
Test -i "3 rb"
+ grep -i '3 rb' /etc/hosts

Ik kon het eigenlijke grep-commando verifiëren (dankzij set -x).


Antwoord 7

U zou een uitbreiding van dit probleem kunnen hebben als uw oorspronkelijke tekst is ingesteld in een tekenreekstypevariabele, bijvoorbeeld:

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
}

In dit geval, als u de status_message variabele niet doorgeeft als string (omringd door “”), wordt deze gesplitst in een reeks van verschillende argumenten.

“$variable”: het huidige nummer is CDE bij DEF van ABC

$variabele: de


Antwoord 8

Ik had hetzelfde soort probleem en in feite was het probleem niet de functie of de functieaanroep, maar wat ik als argumenten aan de functie doorgaf.

De functie werd aangeroepen vanuit de hoofdtekst van het script – de ‘main’ – dus ik gaf “st1 ab” “st2 cd” “st3 ef” door vanaf de opdrachtregel en gaf het door aan de functie met behulp van myFunction $*

De $* veroorzaakt het probleem omdat het zich uitbreidt tot een reeks tekens die zal worden geïnterpreteerd in de aanroep van de functie met witruimte als scheidingsteken.

De oplossing was om de aanroep naar de functie te veranderen in expliciete argumentafhandeling van de ‘main’ naar de functie: de aanroep zou dan myFunction “$1” “$2” “$3” zijn, waardoor de witruimte binnen strings behouden blijft als de aanhalingstekens zullen de argumenten afbakenen…
Dus als een parameter spaties kan bevatten, moet deze expliciet worden behandeld tijdens alle aanroepen van functies.

Omdat dit de reden kan zijn voor lang zoeken naar problemen, is het misschien verstandig om nooit $* te gebruiken om argumenten door te geven…

Other episodes