524 votes

Comment retourner une valeur de chaîne à partir d'une fonction bash

Je voudrais retourner une chaîne d'une fonction bash.

Je vais écrire l'exemple en Java pour montrer ce que je voudrais faire:

public String getSomeString () {
  retour "tadaa";
}

String variable = getSomeString ();

L'exemple ci-dessous fonctionne dans bash, mais y a-t-il une meilleure façon de le faire?

function getSomeString {
   echo "tadaa"
}

VARIABLE = $ (getSomeString)

327voto

Philipp Points 21479

Il n'y a pas de meilleur moyen que je connaisse. Bash ne connaît que les codes d'état (entiers) et les chaînes écrites dans la sortie standard.

207voto

bstpierre Points 12616

On pourrait avoir la prise de fonction d'une variable comme le premier arg et modifier la variable avec la chaîne que vous souhaitez retourner.

#!/bin/bash
set -x
function pass_back_a_string() {
    eval "$1='foo bar rab oof'"
}

return_var=''
pass_back_a_string return_var
echo $return_var

Affiche "foo bar rab d'absence du bureau".

Edit: ajouté en citant à l'endroit approprié pour permettre les espaces de chaîne à l'adresse @Luca Borrione commentaire.

Edit: Comme une démonstration, voir le programme suivant. C'est une solution généraliste: il vous permet même de recevoir une chaîne de caractères dans une variable locale.

#!/bin/bash
set -x
function pass_back_a_string() {
    eval "$1='foo bar rab oof'"
}

return_var=''
pass_back_a_string return_var
echo $return_var

function call_a_string_func() {
     local lvar=''
     pass_back_a_string lvar
     echo "lvar='$lvar' locally"
}

call_a_string_func
echo "lvar='$lvar' globally"

Cette affiche:

+ return_var=
+ pass_back_a_string return_var
+ eval 'return_var='\''foo bar rab oof'\'''
++ return_var='foo bar rab oof'
+ echo foo bar rab oof
foo bar rab oof
+ call_a_string_func
+ local lvar=
+ pass_back_a_string lvar
+ eval 'lvar='\''foo bar rab oof'\'''
++ lvar='foo bar rab oof'
+ echo 'lvar='\''foo bar rab oof'\'' locally'
lvar='foo bar rab oof' locally
+ echo 'lvar='\'''\'' globally'
lvar='' globally

Edit: ce qui démontre que l'original de la valeur de la variable est disponible dans la fonction, comme incorrecte a été critiqué par @Xichen Li dans un commentaire.

#!/bin/bash
set -x
function pass_back_a_string() {
    eval "echo in pass_back_a_string, original $1 is \$$1"
    eval "$1='foo bar rab oof'"
}

return_var='original return_var'
pass_back_a_string return_var
echo $return_var

function call_a_string_func() {
     local lvar='original lvar'
     pass_back_a_string lvar
     echo "lvar='$lvar' locally"
}

call_a_string_func
echo "lvar='$lvar' globally"

Cela donne de sortie:

+ return_var='original return_var'
+ pass_back_a_string return_var
+ eval 'echo in pass_back_a_string, original return_var is $return_var'
++ echo in pass_back_a_string, original return_var is original return_var
in pass_back_a_string, original return_var is original return_var
+ eval 'return_var='\''foo bar rab oof'\'''
++ return_var='foo bar rab oof'
+ echo foo bar rab oof
foo bar rab oof
+ call_a_string_func
+ local 'lvar=original lvar'
+ pass_back_a_string lvar
+ eval 'echo in pass_back_a_string, original lvar is $lvar'
++ echo in pass_back_a_string, original lvar is original lvar
in pass_back_a_string, original lvar is original lvar
+ eval 'lvar='\''foo bar rab oof'\'''
++ lvar='foo bar rab oof'
+ echo 'lvar='\''foo bar rab oof'\'' locally'
lvar='foo bar rab oof' locally
+ echo 'lvar='\'''\'' globally'
lvar='' globally

112voto

Vicky Ronnen Points 301

Toutes les réponses ci-dessus ignorent ce qui a été indiqué dans la page de manuel de bash.

  • Toutes les variables déclarées à l'intérieur d'une fonction seront partagées avec l'environnement appelant.
  • Toutes les variables déclarées locales ne seront pas partagées.

Exemple de code

 #!/bin/bash

f()
{
    echo function starts
    local WillNotExists="It still does!"
    DoesNotExists="It still does!"
    echo function ends
}

echo $DoesNotExists #Should print empty line
echo $WillNotExists #Should print empty line
f                   #Call the function
echo $DoesNotExists #Should print It still does!
echo $WillNotExists #Should print empty line
 

Et sortie

 $ sh -x ./x.sh
+ echo

+ echo

+ f
+ echo function starts 
function starts
+ local 'WillNotExists=It still does!'
+ DoesNotExists='It still does!'
+ echo function ends 
function ends
+ echo It still 'does!' 
It still does!
+ echo
 

Aussi sous pdksh et ksh ce script fait la même chose!

34voto

Markarian451 Points 121

Comme bstpierre ci-dessus, j'utilise et je recommande l'utilisation de nommer explicitement les variables de sortie:

function some_func() # OUTVAR ARG1
{
   local _outvar=$1
   local _result # Use some naming convention to avoid OUTVARs to clash
   ... some processing ....
   eval $_outvar=\$_result # Instead of just =$_result
}

Notez l'utilisation de citer l' $. Cela permettra d'éviter d'interpréter le contenu en $result shell caractères spéciaux. J'ai trouvé que c'est un ordre de grandeur plus rapide que l' result=$(some_func "arg1") idiome de la capture d'un écho. La différence de vitesse est d'autant plus notable à l'aide de bash sur MSYS où stdout capture à partir d'appels de fonction est presque catastrophique.

C'est ok pour l'envoyer dans un local variables car les locaux sont dynamiquement étendues dans bash:

function another_func() # ARG
{
   local result
   some_func result "$1"
   echo result is $result
}

29voto

chiborg Points 7938

Vous pouvez également capturer la sortie de la fonction:

 #!/bin/bash
function getSomeString() {
     echo "tadaa!"
}

return_var=$(getSomeString)
echo $return_var
# Alternative syntax:
return_var=`getSomeString`
echo $return_var
 

On dirait bizarre, mais c'est mieux que d'utiliser des variables globales IMHO. Passer les paramètres fonctionne comme d'habitude, il suffit de les mettre à l'intérieur des accolades ou des backticks.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X