Dans certains coquillages (y compris bash):
IFS=: command eval 'p=($PATH)'
(avec bash, vous pouvez omettre l’ commandémulation si pas dans sh / POSIX). Mais gardez à l'esprit que lorsque vous utilisez des variables non entre guillemets, vous en avez généralement besoin set -f, et il n'y a pas de portée locale pour cela dans la plupart des shells.
Avec zsh, vous pouvez faire:
(){ local IFS=:; p=($=PATH); }
$=PATHconsiste à forcer le fractionnement des mots, ce qui n'est pas fait par défaut dans zsh(la suppression lors du développement de variable n'est pas effectuée non plus, donc vous n'avez pas besoin, set -fsauf dans l'émulation sh).
(){...}(ou function {...}) sont appelées fonctions anonymes et sont généralement utilisées pour définir une étendue locale. avec d'autres shells prenant en charge l'étendue locale dans les fonctions, vous pouvez faire quelque chose de similaire avec:
e() { eval "$@"; }
e 'local IFS=:; p=($PATH)'
Pour implémenter une portée locale pour les variables et les options dans les shells POSIX, vous pouvez également utiliser les fonctions fournies à l' adresse https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh . Ensuite, vous pouvez l'utiliser comme:
. /path/to/locvar.sh
var=3,2,2
call eval 'locvar IFS; locopt -f; IFS=,; set -- $var; a=$1 b=$2 c=$3'
(Soit dit en passant, il est incorrect de diviser de $PATHcette façon ci-dessus, sauf zshque, comme dans les autres shells, IFS est un délimiteur de champ, et non un séparateur de champ).
IFS=$'\n' a=($str)
Est-ce juste deux missions, l'une après l'autre, tout comme a=1 b=2.
Une note d'explication sur var=value cmd:
Dans:
var=value cmd arg
Le shell s'exécute /path/to/cmddans un nouveau processus et passe cmdet argdans argv[]et var=valuedans envp[]. Ce n'est pas vraiment une affectation de variable, mais davantage de variables d'environnement transmises à la commande exécutée . Dans le shell Bourne ou Korn, avec set -k, vous pouvez même l'écrire cmd var=value arg.
Cela ne s'applique pas aux fonctions intégrées ou aux fonctions qui ne sont pas exécutées . Dans le shell Bourne, dans var=value some-builtin, varfinit par être défini, comme avec un var=valueseul. Cela signifie par exemple que le comportement de var=value echo foo(ce qui n’est pas utile) varie selon qu’il echosoit intégré ou non.
POSIX et / ou ont kshmodifié ce comportement en ce sens que le comportement Bourne ne se produit que pour une catégorie de fonctions intégrées appelées fonctions spéciales . evalest un spécial intégré, readn'est pas. Pour les commandes intégrées non spéciales, les var=value builtinensembles varne concernent que l'exécution de la commande intégrée, ce qui lui permet de se comporter de manière similaire à l'exécution d'une commande externe.
La commandcommande peut être utilisée pour supprimer l' attribut spécial de ces fonctions spéciales . Ce qui est bien négligé Posix que pour les evalet .builtins, cela voudrait dire que des obus aurait à mettre en œuvre une pile variable (même si elle ne précise pas les localou la typesetportée de limitation des commandes), parce que vous pouvez faire:
a=0; a=1 command eval 'a=2 command eval echo \$a; echo $a'; echo $a
Ou même:
a=1 command eval myfunction
avec myfunctionêtre une fonction à l' aide ou la mise $aet potentiellement appeler command eval.
C'était vraiment un oubli parce que ksh(la spécification est principalement basée sur) ne l'a pas implémentée (et AT & T kshet zshne le fait toujours pas), mais de nos jours, à l'exception de ces deux là, la plupart des shells l'implémentent. Le comportement varie selon les coquillages, par exemple:
a=0; a=1 command eval a=2; echo "$a"
bien que. L'utilisation localsur les shells qui le supportent constitue un moyen plus fiable d'implémenter la portée locale.
IFS=: command eval …définitIFSque pour la durée deeval, comme prescrit par POSIX, en dash, pdksh et bash, mais pas en ksh 93u. Il est inhabituel de voir que ksh est l'intrus-non-conforme-un-out.