web-dev-qa-db-fra.com

Passer une chaîne avec des espaces comme argument de fonction dans bash

J'écris un script bash dans lequel je dois passer une chaîne contenant des espaces à une fonction de mon script bash.

Par exemple:

#!/bin/bash

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

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

Une fois exécuté, le résultat attendu serait:

firstString
second string with spaces
thirdString

Cependant, ce qui est réellement produit est:

firstString
second
string

Est-il possible de passer une chaîne avec des espaces comme argument unique à une fonction dans bash?

148
Grant Limberg

vous devriez mettre des guillemets et aussi, votre déclaration de fonction est fausse.

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

Et comme les autres, ça marche aussi pour moi. Dites-nous quelle version de Shell vous utilisez.

153
ghostdog74

Une autre solution au problème ci-dessus consiste à définir chaque chaîne sur une variable, appelez la fonction avec des variables désignées par un signe dollar littéral \$. Ensuite, dans la fonction, utilisez eval pour lire la variable et la sortie comme prévu.

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

La sortie est alors:

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

En essayant de résoudre un problème similaire à celui-ci, je tombais sur le problème d'UNIX en pensant que mes variables étaient délimitées par des espaces. J'essayais de transmettre une chaîne délimitée par des tubes à une fonction en utilisant awk pour définir une série de variables utilisées ultérieurement pour créer un rapport. Au départ, j'avais essayé la solution publiée par ghostdog74 mais je ne pouvais pas la faire fonctionner, car tous mes paramètres n'étaient pas passés entre guillemets. Après avoir ajouté des guillemets à chaque paramètre, il a commencé à fonctionner comme prévu.

Ci-dessous, l'état avant de mon code et pleinement opérationnel après l'état.

Avant - Code de non-fonctionnement

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

Après - Code de fonctionnement

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

La solution la plus simple à ce problème est qu'il vous suffit d'utiliser \" pour les arguments séparés par des espaces lorsque vous exécutez un script Shell:

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

Votre définition de myFunction est fausse. CA devrait etre:

myFunction()
{
    # same as before
}

ou:

function myFunction
{
    # same as before
}

Quoi qu'il en soit, cela a l'air bien et fonctionne bien pour moi sur Bash 3.2.48.

5
R Samuel Klatchko

J'ai 9 ans de retard mais un moyen plus dynamique serait

function myFunction 
{
   for i in $*; do echo $i; done;
}
1
Raimi bin Karim

Solution simple qui a fonctionné pour moi - citée $ @

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

Je pouvais vérifier la commande grep réelle (grâce à set -x).

1
Bin TAN - Victor