Un script bash qui contient
for i in {a,b}-{1,2}; do
echo $i;
done
impressions
a-1
a-2
b-1
b-2
une fois exécuté. C'est ce que j'attendais - à mesure que la {a,b}
construction est développée.
Cependant, quand (un autre) script contient
v={a,b}-{1,2}
echo $v
il imprime
{a,b}-{1,2}
ce qui n'est pas ce que j'attendais. Je m'attendais à ce qu'il s'imprime a-1 a-2 b-1 b-2
. De toute évidence, la {a,b}
construction n'est pas développée.
Je peux le faire grandir comme ça
v=$(echo {a,b}-{1,2})
Sur la base de ces observations, j'ai deux questions: 1) quand la {a,b}
construction est-elle développée? 2) est $(echo {a,b}-{1,2})
la meilleure façon de déclencher une expansion si nécessaire?
bash
brace-expansion
René Nyffenegger
la source
la source
=
. Par exemple,v=a-1 a-2
ne fonctionnera pas.v=a-1 a-2
signifieassign 'a-1' to variable v and run 'a-2'
v=(a-1 a-2)
attribue le tableau à la variablev
.v+=(b-1 b-2)
s'y ajoute.Réponses:
Le manuel de Bash dit que:
L'extension d'accolade n'est pas dans la liste, elle n'est donc pas effectuée pour l'affectation
v={a,b}-{1,2}
. Comme mentionné par @Wildcard, l'expansion simplev=a-1 v=b-1 ...
serait de toute façon insensée.De plus, lors de l'exécution de
echo $v
, les règles suivantes s'appliquent:L'expansion d'accolade se produit avant l'expansion variable, donc les accolades affectées à
$v
ne sont pas développées.Mais vous pouvez faire des trucs comme ça:
Le développer avec
$(echo ...)
devrait fonctionner si vous n'avez aucun espace dans la chaîne à développer, et ne rencontrerez donc pas de problèmes avec le fractionnement de mots. Une meilleure façon pourrait être d'utiliser une variable de tableau si vous le pouvez.Par exemple, enregistrez l'expansion dans un tableau et exécutez une commande avec les valeurs étendues:
la source
Un point intéressant. L'extrait suivant est peut-être utile
man bash
:Notez que l'expansion d'accolade n'est PAS mentionnée dans la liste.
Cependant, cela laisse encore une question, à savoir: comment le shell sait-il qu'il s'agit d'une affectation variable et donc non soumise à l'expansion d'accolade? Ou plus précisément, où la séquence d'analyse est-elle clarifiée et codifiée de telle sorte que le shell est défini pour identifier les affectations de variables avant de gérer l'expansion de l'accolade? (C'est évidemment ainsi que cela
bash
fonctionne, mais je n'ai pas trouvé la ligne exacte de la documentation décrivant cela.)la source
LESS=+/SIMPLE man bash
).selon mes connaissances, le {a, b, c} est développé lorsqu'il est directement répercuté ou utilisé avec une commande, par exemple: mkdir ~ / {a, b, c}, mais lorsqu'il est défini sur une variable, il doit être évalué avant l'écho ou en l'utilisant comme argument!
puisque vous avez "a" suivi de "b" dans l'ordre alpha [az] et "1" suivi de "2" dans l'ordre dec [0-9]: vous pouvez utiliser le double point ".." insteed of comma ", "
la source
v
n'a pas été définie . Ou du moins pourquoi aucune erreur n'a été générée lorsque vous tapez la commande:v=a-1 v=a-2 v=b-1 v=b-2
(à laquelle vous vous attendez à ce que l'affectation de variable soit étendue). C'est une bonne question; cela n'y répond pas vraiment.L'affectation à une variable dans bash ne développe pas l'expression.
Pour ce petit script, x contiendra
"*"
et non l'extension de"*"
:Cependant, certaines valeurs sont développées, réf. la belle réponse d'ilkkachu.
Les expressions sont développées lorsqu'elles sont évaluées.
Comme ça:
Ou comme ça:
Ou comme ça:
Le déclenchement
$()
est assez courant et je pense qu'il est préférable àeval
, mais le mieux est probablement de ne pas déclencher d'évaluation du tout, jusqu'à ce que la variable soit réellement utilisée dans une commande.la source