web-dev-qa-db-fra.com

Comment attribuer la sortie d'une fonction à une variable à l'aide de bash?

J'ai une fonction bash qui produit une sortie:

function scan {
  echo "output"
}

Comment puis-je affecter cette sortie à une variable?

c'est à dire. VAR = scan (bien sûr, cela ne fonctionne pas - cela donne VAR égal à la chaîne "scan")

64
Brent
VAR=$(scan)

Exactement de la même manière que pour les programmes.

100
Robert Obryk

Vous pouvez utiliser les fonctions bash dans les commandes/pipelines comme vous utiliseriez normalement des programmes. Les fonctions sont également disponibles pour les sous-réservoirs et de manière transitoire, Commande Substitution:

VAR=$(scan)

C’est le moyen le plus simple d’atteindre le résultat souhaité dans la plupart des cas. Je décrirai les cas spéciaux ci-dessous.

Préserver les nouvelles lignes suivantes:

L'un des effets secondaires (généralement utiles) de la substitution de commandes est qu'elle supprime un nombre illimité de nouvelles lignes. Si vous souhaitez conserver les nouvelles lignes de fin, vous pouvez ajouter un caractère factice à la sortie du sous-shell, puis le supprimer avec le développement de paramètres.

function scan2 () {
    local nl=$'\x0a';  # that's just \n
    echo "output${nl}${nl}" # 2 in the string + 1 by echo
}

# append a character to the total output.
# and strip it with %% parameter expansion.
VAR=$(scan2; echo "x"); VAR="${VAR%%x}"

echo "${VAR}---"

impressions (3 nouvelles lignes conservées):

output


---

Utiliser un paramètre de sortie: éviter le sous-shell (et préserver les nouvelles lignes)

Si l'objectif de la fonction est de "retourner" une chaîne dans une variable, avec bash v4.3 et plus, vous pouvez utiliser ce qu'on appelle un nameref Namerefs permet à une fonction de prendre le nom d'un ou de plusieurs paramètres de sortie de variables. Vous pouvez assigner des choses à une variable nameref, et c'est comme si vous changiez la variable sur laquelle elle pointe/fait référence.

function scan3() {
    local -n outvar=$1    # -n makes it a nameref.
    local nl=$'\x0a'
    outvar="output${nl}${nl}"  # two total. quotes preserve newlines
}

VAR="some prior value which will get overwritten"

# you pass the name of the variable. VAR will be modified.
scan3 VAR

# newlines are also preserved.
echo "${VAR}==="

impressions:

output

===

Ce formulaire présente quelques avantages. Cela permet notamment à votre fonction de modifier l'environnement de l'appelant sans utiliser les variables globales partout.

Remarque: l'utilisation de namerefs peut améliorer considérablement les performances de votre programme si vos fonctions reposent fortement sur les commandes intégrées bash, car elles évitent la création d'un sous-shell jeté juste après. Cela est généralement plus logique pour les petites fonctions réutilisées souvent par exemple, les fonctions se terminant par echo "$returnstring"

Ceci est pertinent. https://stackoverflow.com/a/38997681/5556676

12
init_js

Je pense que init_js devrait utiliser declare au lieu de local!

function scan3() {
    declare -n outvar=$1    # -n makes it a nameref.
    local nl=$'\x0a'
    outvar="output${nl}${nl}"  # two total. quotes preserve newlines
}
0
Hamid Reza Hasani