L'idée de base est que les VAR=VALUE some-commandjeux VARà VALUEl'exécution de some-commandquand some-commandest une commande externe, et il ne reçoit pas plus de fantaisie que cela. Si vous combinez cette intuition avec une certaine connaissance du fonctionnement d'un shell, vous devriez trouver la bonne réponse dans la plupart des cas. La référence POSIX est «Simple Commands» dans le chapitre «Shell Command Language» .
Si some-commandest une commande externe , VAR=VALUE some-commandéquivaut à env VAR=VALUE some-command. VARest exporté dans l'environnement de some-command, et sa valeur (ou son absence) dans le shell ne change pas.
Si some-commandest une fonction , alors VAR=VALUE some-commandest équivalent à VAR=VALUE; some-command, c'est- à -dire que l'affectation reste en place après le retour de la fonction et que la variable n'est pas exportée dans l'environnement. La raison en est liée à la conception du shell Bourne (et par la suite à la compatibilité descendante): il n'avait pas la possibilité de sauvegarder et de restaurer les valeurs des variables autour de l'exécution d'une fonction. Ne pas exporter la variable est logique car une fonction s'exécute dans le shell lui-même. Cependant, ksh (y compris ATT ksh93 et pdksh / mksh), bash et zsh implémentent le comportement le plus utile où VARest défini uniquement pendant l'exécution de la fonction (il est également exporté). Dans ksh , cela se fait si la fonction est définie avec la syntaxe kshfunction NAME …, pas s'il est défini avec la syntaxe standard NAME (). En bash , cela se fait uniquement en mode bash, pas en mode POSIX (lorsqu'il est exécuté avec POSIXLY_CORRECT=1). Dans zsh , cela se fait si l' posix_builtinsoption n'est pas définie; cette option n'est pas définie par défaut mais est activée par emulate shou emulate ksh.
Si some-commandest une fonction intégrée, le comportement dépend du type de fonction intégrée. Les éditions spéciales se comportent comme des fonctions. Les fonctions intégrées spéciales sont celles qui doivent être implémentées à l'intérieur du shell car elles affectent le shell d'état (par exemple, breakaffectent le flux de contrôle, cdaffectent le répertoire courant, setaffectent les paramètres et options de position…). D'autres fonctions intégrées sont intégrées uniquement pour des raisons de performances et de commodité (principalement - par exemple, la fonction bash printf -vne peut être implémentée que par une fonction intégrée), et elles se comportent comme une commande externe.
L'affectation a lieu après l'expansion de l'alias, donc s'il some-commands'agit d'un alias , développez-le d'abord pour trouver ce qui se passe.
Notez que dans tous les cas, l'affectation est effectuée après l'analyse de la ligne de commande, y compris toute substitution de variable sur la ligne de commande elle-même. var=a; var=b echo $varImprime donc a, car $varest évalué avant que l'affectation n'ait lieu. Et IFS=. printf "%s\n" $varutilise donc l'ancienne IFSvaleur pour se diviser $var.
J'ai couvert tous les types de commandes, mais il y a un autre cas: quand il n'y a pas de commande à exécuter , c'est-à-dire si la commande se compose uniquement d'affectations (et éventuellement de redirections). Dans ce cas, l'affectation reste en place . VAR=VALUE OTHERVAR=OTHERVALUEest équivalent à VAR=VALUE; OTHERVAR=OTHERVALUE. Donc, après IFS=. arr=($var), IFSreste réglé sur .. Étant donné que vous pouvez utiliser $IFSdans l'affectation à arren supposant qu'il a déjà sa nouvelle valeur, il est logique que la nouvelle valeur de IFSsoit utilisée pour l'expansion de $var.
En résumé, vous pouvez utiliser uniquement IFSpour le fractionnement temporaire de champs:
- en lançant un nouveau shell ou un sous-shell (par exemple,
third=$(IFS=.; set -f; set -- $var; echo "$3")c'est une façon compliquée de faire third=${var#*.*.}sauf qu'ils se comportent différemment lorsque la valeur de varcontient moins de deux .caractères);
- en ksh,
IFS=. some-functionoù some-functionest défini avec la syntaxe ksh function some-function …;
- en bash et zsh, avec
IFS=. some-functiontant qu'ils fonctionnent en mode natif par opposition au mode de compatibilité.
IFSreste réglé sur." Eek. Après avoir lu la première partie, cela a du sens, mais avant de poster ce Q, je ne m'y attendais pas.