2 votes

Utilisation conjointe de l'évaluation et de l'écho

Je voudrais savoir si le code ci-dessous peut être amélioré ou si la façon dont il est écrit est la bonne. Si ce n'était pas clair, je suis un débutant en bash mais mon script remplit son rôle.

Ce code tente de définir les variables s$counter= s1, s2, s3, s4... en fonction des variables définies précédemment s1$j y s2$j avec j une chaîne de caractères qui est un élément d'une liste (toutes définies précédemment).

counter=1 
for j in ${list[@]}
    do
            eval s$counter=$(eval "echo \$s1$j")
            eval s$((counter+1))=$(eval "echo \$s2$j")
            counter=$((counter+2))
    done

L'intérieur eval , c'est-à-dire $(eval "echo \$s1$j") es est censé renvoyer la valeur de s1$j . Le deuxième eval , c'est-à-dire l'évaluation s$counter =... est destiné à définir les variables s1, s2, s3, s4 ...

Voici un exemple : disons que pour la première boucle avant j=a puis $(eval "echo \$s1$j") == $s1a avec la valeur de s1a défini plus tôt dans le script, par exemple " s1a=10 "de sorte que lorsque le deuxième eval est évaluée, nous avons le commandement qui dit " s1=10 ".

Cela fonctionne, mais est-ce qu'il pourrait se produire quelque chose qui en ferait une menace pour la mémoire ou quelque chose de ce genre ?

Même chose avec cette ligne de code.

eval $(echo "sed -i '$(eval echo '17i$sed17line')' $file")

sed17line c'est ce que je veux ajouter à la ligne 17 de file . Cela dépend de ce pour quoi je veux utiliser le script, c'est pourquoi je l'utilise comme une variable et c'est pourquoi j'utilise une combinaison de echo y eval .

1voto

Kamil Maciorowski Points 57004

Il est bon de savoir qu'il y a des problèmes avec les eval ( cette y cette ) et echo ( aquí ). Il convient d'éviter eval Il est facile de l'utiliser à mauvais escient.

Même si ces commandes sont tout à fait sûres dans votre cas particulier, je vous conseille de laisser tomber eval . Votre code est en effet trop compliqué à cause de cela.


Votre premier exemple est beaucoup plus clair avec les tableaux. Cela fonctionne avec GNU bash 4.4.12 dans ma Debian :

# preparing variables
unset -v list s s1 s2
declare -a list=( foo 'X Y' bar baz )
declare -a s
declare -A s1=( [foo]='FOO 1' [bar]='BAR 2' [baz]='BAZ beep; eject /dev/sr0' )
declare -A s2=( [foo]='oof oof' [bar]='rab rab' [baz]='zab zab' [X Y]='9')

# your code rewritten, we don't even need a counter
for j in "${list[@]}"
  do
    s+=( "${s1[$j]}" "${s2[$j]}" )
  done

# checking contents of s
printf '%s\n' "${s[@]}"

Conseil : recherchez les termes "tableaux indexés", "tableaux associatifs" et leur utilisation dans les documents suivants bash .

Notez l'élément avec l'espace ( X Y ) n'a rien de spécial pour moi ; mais cela casserait votre code. Je peux aussi avoir BAZ beep; eject /dev/sr0 en mi s1 ; je vous mets au défi de mettre s1baz='BAZ beep; eject /dev/sr0' , ont baz dans votre list exécutez votre code et voyez ce qui se passe. Voici ce qui se passe eval est capable de le faire. Imaginez maintenant que je mette rm -rf ~/ 代わりに eject … .


Le deuxième exemple peut être grandement simplifié comme suit :

sed -i "17i$sed17line" "$file"

Vous semblez avoir un parti pris pour eval + echo puisque vous avez créé un dispositif qui les utilise deux fois alors qu'il n'y en a pas besoin. C'est peut-être parce que vos variables ne sont pas toujours étendues à leurs valeurs lorsque vous le souhaitez ; si c'est le cas, examinez la différence entre les variables simples ( ' ) et les guillemets doubles ( " ) en bash .

Bravo d'avoir des doutes et de poser la question.

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