2009-12-30 9 views
107

J'écris un script bash où j'ai besoin de passer une chaîne contenant des espaces à une fonction dans mon script bash.Passer une chaîne avec des espaces comme argument de fonction dans bash

Par exemple:

#!/bin/bash 

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

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

Effectué, la sortie je pense est:

firstString 
second string with spaces 
thirdString 

Cependant, ce qui est en fait la sortie est:

firstString 
second 
string 

est-il un moyen passer une chaîne avec des espaces comme argument unique à une fonction dans bash?

+0

Works pour moi ... J'utilise la syntaxe complète des fonctions si » fonction (bla) {echo $ 1; } ", ne peut pas faire un court dans un seul doublure Pas sûr que cela fait une différence Quelle version de bash? – Eugene

+3

essayez' echo "$ @" 'ou' pour i dans "$ @"; faire echo $ i; done' pour utiliser correctement les paramètres entre guillemets contenant des espaces.Ceci est très clairement mentionné dans toute la documentation 'bash' sous la section' positional parameters' – Samveen

+1

J'ai eu un problème similaire, en essayant de passer une chaîne entre guillemets comme paramètre et seulement le premier Le mot de la chaîne étant reconnu comme faisant partie du paramètre, la suggestion de Samveen de changer $ 1 en $ @ a fonctionné pour moi.Notez que je ne faisais passer qu'un seul paramètre à la fonction, mais si j'avais passé plus en utilisant l'instruction for –

Répondre

116

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.

+1

Cela fonctionne très bien pour moi aussi. nous appelons une autre fonction à l'intérieur de myFu nction passe ensuite les arguments avec des guillemets. Bravo :) – minhas23

+1

Pouvez-vous expliquer pourquoi on a besoin de citations? J'ai essayé avec et sans, et ça n'a pas marché pour moi. J'utilise Ubuntu 14.04, GNU bash, version 4.3.11 (1) -release (x86_64-pc-linux-gnu). Ce qui * fonctionne * pour moi utilise $ @ (avec ou sans guillemets). –

4

Votre définition de myFunction est erronée. Il devrait être:

myFunction() 
{ 
    # same as before 
} 

ou:

function myFunction 
{ 
    # same as before 
} 

Quoi qu'il en soit, il semble bien et fonctionne très bien pour moi sur Bash 3.2.48.

-2

Avait le même genre de problème et en fait le problème n'était pas la fonction ni l'appel de la fonction, mais ce que je passais comme arguments à la fonction. La fonction a été appelée depuis le corps du script - le 'principal' - j'ai donc passé "st1 ab" "st2 cd" "st3 ef" de la ligne de commande et je l'ai passé à la fonction en utilisant myFunction $ * Le $ * provoque le problème comme il se développe dans un ensemble de caractères qui seront interprétés dans l'appel à la fonction en utilisant des espaces comme un délimiteur. La solution consistait à changer l'appel à la fonction dans la gestion des arguments explicites de 'main' vers la fonction: l'appel serait alors myFunction "$ 1" "$ 2" "$ 3" qui préservera les espaces à l'intérieur des chaînes les guillemets délimiteront les arguments ... Donc si un paramètre peut contenir des espaces, il doit être traité explicitement dans tous les appels de fonctions.

Comme cela peut être la raison de longues recherches à des problèmes, il peut être sage de ne jamais utiliser $ * pour passer des arguments ...

Hope this helps quelqu'un, un jour, quelque part ... janvier

+0

La bonne réponse est '" $ @ "', pas tous les cotés '" $ 1 "', '" $ 2 "', ... les paramètres positionnels ni '$ *'. – Samveen

0

vous pourriez avoir une extension de ce problème dans le cas de votre texte initial a été fixé dans une variable de type chaîne, par exemple:

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 
} 

dans ce cas, si vous ne passez pas la variable status_message avant en tant que chaîne (entouré de "") ce sera divisé en une monture d'arguments différents.

"$ variable": La piste actuelle est CDE au DEF par ABC

variables $: Le

+0

OP a utilisé 'myFunction" firstString "" deuxième chaîne avec des espaces "" thirdString "' et cela n'a pas fonctionné pour lui.Donc ce que vous proposez ne s'applique pas à cette question. – doubleDown

14

Une autre solution à la question ci-dessus est de mettre chaque chaîne à une variable, appel 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 

sortie est alors:

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

En essayant de résoudre un problème similaire à cela, je courais dans la question d'UNIX à penser mes variables ont été l'espace delimeted. J'essayais de passer une chaîne délimitée par un tuyau à une fonction en utilisant awk pour définir une série de variables utilisées plus tard pour créer un rapport. J'ai d'abord essayé la solution postée par ghostdog74 mais je n'ai pas réussi à 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 son état après fonctionnement.

Avant - code 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 
0

solution simple qui a fonctionné pour moi - Cotés $ @

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

je pouvais vérifier la réelle commande grep (merci à set -x).

0

La solution la plus simple à ce problème est que vous avez juste besoin d'utiliser \ « pour l'espace arguements lors de l'exécution seperated un script shell #!/bin/bash myFunction { echo $1 echo $2 echo $3 } myFunction "firstString" "\"Hello World\"" "thirdString"

Questions connexes