2016-03-25 1 views
1

Je travaille actuellement sur le nettoyage de certains scripts shell. Tout en faisant cela, je suis tombé sur quelque chose qui ressemble à ceci:Comprendre l'indirection

if [ ${#VARA} -eq 0 ] || [ ${#$VARB} -eq 0 ] || [ ${$VARC} -eq 0 ]; then 
    ... 
fi 

Comme vous pouvez le voir, il y a trois différents types de choses qui se passent ici avec des variables: ${#V}, ${#$V} et ${$V}. J'aimerais une explication de chacun de ces s'il vous plaît. (Plus Shellcheck is complaining à propos du dernier.)

+1

Mon bash se plaint déjà de la 2ème. Quelle coque est-ce? Toute chance que l'auteur original ne savait pas ce qu'il faisait et juste essayé tous les trois. Le premier est la longueur de chaîne de la valeur VARAs. – Harald

+0

@Harald il y a une très bonne chance de cela. Et oui, c'est Bash. La ligne en question est dans un très grand script. Je ne peux pas promettre qu'il est même utilisé, mais je pensais juste que c'était intéressant puisque je n'avais jamais vu la syntaxe auparavant. –

+0

Pas étonnant que tu ne l'aies pas vu, si ça ne marche pas (sauf le 1er) :-) Ou peut-être que ça fonctionnait dans les anciennes versions de bash. – Harald

Répondre

1

Cette syntaxe fait partie de l'expansion des paramètres shell POSIX (thinking Bash). Il compte le nombre de caractères pour une variable:

$ myvar="foo" && echo ${#myvar} 
3 

Les deux derniers ${#$VARB} et ${$VARC} ont pas une syntaxe valide. Vous ne pouvez pas déclarer une variable de cette façon.

assez similaire à votre ${$VARC} est le \$$myvar valide, utilisé pour indirect reference avec eval ou echo. Cette syntaxe fait référence à la chaîne littérale "$foo" (lorsque myvar="foo"). Comme @chepner mentionné, because of eval, il n'est pas recommandé de l'utiliser. Le Bash 2.0 a introduit la syntaxe ${!myvar} pour la référence de variable indirecte qui est une alternative préférable.

Remarque: vous devez éviter les majuscules pour les noms de variables à ne pas confondre avec les variables shell qui sont également mises en majuscules par convention.

+1

'$ {# myvar}' n'est pas simplement 'bash', mais fait partie de la spécification du shell POSIX. – chepner

+1

'othervar = \ $$ VARC' définit' othervar' à la chaîne littérale '$ foo' (si' foo' est l'expansion de '$ VARC'). – chepner

+0

Merci @chepner. Mise à jour de ma formulation approximative. – SLePort