7 votes

bash - retourne un tableau depuis une fonction et affiche son contenu

Après quelques études et expérimentations, je suis coincé avec le retour d'un tableau à partir d'une fonction, et je n'arrive pas à voir mon erreur.

En bref, ce que cela devrait/doit faire est d'utiliser une fonction avoir une fonction qui lit les valeurs/chaînes d'un fichier et renvoie un tableau :

  • déclarer un tableau : clients
  • assigner le tableau de retour de la fonction aux clients du tableau
  • clients du réseau d'affichage

Il me semble que la fonction lit le fichier entier et non ligne par ligne, mettant ainsi toutes les chaînes dans une seule cellule du tableau, et je ne suis pas sûr de savoir comment afficher explicitement les clients[0] car ce $(clients[0]) échoue dans le code bash

Si, par hasard, je fais quelque chose d'incorrect, veuillez me le signaler ou me faire part de toute suggestion d'optimisation.

#!/bin/bash
readArray(){
        local array=()
        local i=0;
        local j=0
        while IFS= read -r LINE  && [[ -n "$LINE" ]] ; do 
                array[$((i++))]+=${LINE}; # Append line to the array
                ((j++))
        done < "$1";
        rtr=${array[@]}
}
string="/home/cybex/openvpntest/openvpn.log"
declare -a clients
#sed -i '/^$/d' $string
clients=$(readArray "$string")
echo "${clients[@]}"

echo -e "array not empty, displaying array contents\n"

for i in "${!clients[@]}"; do 
  echo "$i: ${clients[$i]}"
done
echo -e "\nfinished displaying contents of array"

cat openvpn.log

something
anotherthing
anotherlineoftext
here is one more line
and lastly
one with 
a few spaces
nice

UPDATE Pour ceux qui veulent voir comment j'ai résolu ce problème :

  • déclarer un tableau "global" avec

    declare -a clients
  • pendant que la fonction s'exécute, ajouter des valeurs DIRECTEMENT au tableau des clients

Pour afficher une seule position d'index d'un tableau, réf. à la dernière ligne de code

echo "${clients[0]}"      or any other number >=0

Code de travail :

declare -a clients
readArray(){
        local array=()
        local i=0;
        local j=0
        while IFS= read -r LINE  && [[ -n "$LINE" ]] ; do 
                clients[$((i++))]+=${LINE}; # Append line to the array
                ((j++))
        done < "$1";
}
string="/home/cybex/openvpntest/openvpn.log"
sed -i '/^$/d' $string
readArray "$string"
echo "${clients[@]}"

echo -e "array not empty, displaying array contents\n"

for i in "${!clients[@]}"; do 
  echo "$i: ${clients[$i]}"
done
echo -e "\nfinished displaying contents of array"
echo "${clients[0]}"

4voto

arney Points 153

Déjà répondu aquí .

Vous devriez faire une recherche minimale dans google, car c'était le premier lien retourné pour "bash return array".

編集する。

En bash, les fonctions ne renvoient pas de valeurs. Elles peuvent retourner un état (comme les autres programmes).

Donc, si vous voulez retourner quelque chose, vous devez utiliser des variables globales qui sont mises à jour à l'intérieur de votre fonction.

0 votes

J'ai vu cela parmi beaucoup d'autres, mais cela n'a pas de sens pour moi. Qu'est-ce que je dois chercher ? un return, un declare, qu'est-ce qui renvoie le tableau ?

0 votes

Mise à jour : ok, c'est logique, je n'ai pas trouvé de post mentionnant cela, merci

0 votes

@cybex Je pense avoir une réponse.

1voto

Equinox Points 1831

Discussion

Si vous êtes arrivé au point de vouloir retourner un tableau à partir d'une fonction, vous savez probablement que vous ne pouvez retourner que des codes d'état. Boo ! Vous dites :-)

Que pouvons-nous faire avec d'autres données dans une fonction que nous voulons utiliser dans une autre fonction / contexte ?

  1. echo

En supposant que stdout est défini sur le terminal, vous pouvez au moins voir le contenu d'une variable ou autre.

  1. Redirection des sorties : > o >>

Pas idéal, mais possible :-) Il y a probablement d'autres choses que vous pouvez faire, mais arrêtons-nous là.

Suite de la discussion ...

Disons que l'option 1 ci-dessus semble prometteuse. Que se passe-t-il généralement ? Quelque chose comme ça ...

function listToString ()
{
    echo "$*"
}

Référence : Votre UNIX : The Ultimate Guide, 2ème édition, p. 387 (dernier paragraphe) .

Si j'appelle doSomething il peut, par exemple, envoyer un message de type chaîne de caractères à stdout. Cette sortie peut être capturée de deux manières différentes.

  1. Backticks `faire quelque chose`
  2. Cette chose : $(doSomthing)

Si c'est vrai, alors vous pouvez enregistrer dans un autre contexte ce que vous envoyez à stdout.

var1=`doSomething`

o

var1=$(doSomething)

En résumé, ....

Convertit une liste en une chaîne de caractères. Faire écho à la chaîne de caractères. Capturez la chaîne de caractères renvoyée avec la substitution de commande (voir ci-dessus). Utilisez read combiné avec un ici la chaîne ( <<< ) pour convertir la chaîne de caractères en un tableau. Utilisez le tableau à votre guise.

Fichier : new_users

fsmith
jdoe

Disons que nous voulons ajouter de nouveaux utilisateurs avec une fonction que nous avons créée et qui s'appelle addAccounts qui boucle sur les arguments du nom d'utilisateur. L'ordre de marche serait le suivant .

  1. Faire un fichier
  2. Lire le dossier
  3. Convertir une liste en une chaîne de caractères
  4. Convertit la chaîne de caractères en un tableau.

Le code serait quelque chose comme ceci

function listToString ()
{
    echo "$*"
}

usersString=$(listToString $(cat new_users))

read -a users <<< $usersString

addAccounts "${users[@]}"

listToString peut ne pas fonctionner avec toutes les lignes d'entrée. Testez-le sur vos données.

La dernière ligne devrait se résoudre à :

addAccounts "fsmith" "jdoe"

De nombreuses personnes ne comprendront pas la ligne ...

read -a users <<< $usersString

... parce qu'ils n'ont jamais entendu parler d'une corde ici.

Cette solution ne permet pas de transmettre un tableau à partir d'une fonction, mais elle vous permet de convertir la sortie d'une fonction en un tableau. Certains se contentent de convertir une liste en chaîne de caractères et de s'en tenir là, mais si vous voulez vraiment utiliser un tableau officiel de bash, le sting ci-dessus le fera pour vous.

0voto

Daniel Trugman Points 103

Cette astuce ne fonctionnera pas toujours (lorsque vous avez des valeurs avec des espaces, ou que vous voulez retourner des valeurs qui dépendent des valeurs d'entrée), mais elle fait généralement le travail :

array_returning_func() {
    echo "cat dog tree"
}

declare -a arr="$(array_returning_func)"
for obj in ${arr[@]}; do
    echo "$obj"
done

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X