In alcune shell (incluso bash):
IFS=: command eval 'p=($PATH)'
(con bash, è possibile omettere l' commandemulazione if / if di sh / POSIX). Ma attenzione che quando si utilizzano variabili non quotate, in genere è anche necessario set -f, e nella maggior parte delle shell non esiste un ambito locale per questo.
Con zsh, puoi fare:
(){ local IFS=:; p=($=PATH); }
$=PATHè forzare la suddivisione delle parole che non viene eseguita per impostazione predefinita in zsh(non si fa neppure il gomito sull'espansione variabile, quindi non è necessario set -fse non in emulazione).
(){...}(o function {...}) sono chiamate funzioni anonime e in genere vengono utilizzate per impostare un ambito locale. con altre shell che supportano l'ambito locale nelle funzioni, potresti fare qualcosa di simile con:
e() { eval "$@"; }
e 'local IFS=:; p=($PATH)'
Per implementare un ambito locale per variabili e opzioni nelle shell POSIX, è anche possibile utilizzare le funzioni fornite su https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh . Quindi puoi usarlo come:
. /path/to/locvar.sh
var=3,2,2
call eval 'locvar IFS; locopt -f; IFS=,; set -- $var; a=$1 b=$2 c=$3'
(a proposito, non è valido dividere in $PATHquesto modo sopra tranne che zshcome in altre shell, IFS è delimitatore di campo, non separatore di campo).
IFS=$'\n' a=($str)
Sono solo due incarichi, uno dopo l'altro, proprio come a=1 b=2.
Una nota di spiegazione su var=value cmd:
Nel:
var=value cmd arg
L'esecuzione della shell /path/to/cmdin un nuovo processo e passaggi cmde argin argv[]e var=valuein envp[]. Non si tratta in realtà di un'assegnazione di variabili, ma più di passare le variabili d'ambiente al comando eseguito . Nella shell Bourne o Korn, con set -k, puoi persino scriverlo cmd var=value arg.
Ora, ciò non si applica ai builtin o alle funzioni che non vengono eseguite . Nella shell Bourne, in var=value some-builtin, varfinisce per essere impostato in seguito, proprio come da var=valuesolo. Ciò significa ad esempio che il comportamento di var=value echo foo(che non è utile) varia a seconda che echosia incorporato o meno.
POSIX e / o kshcambiato quello in quanto quel comportamento Bourne si verifica solo per una categoria di builtin chiamati builtin speciali . evalè un builtin speciale, readnon lo è. Per builtin non speciale, var=value builtinimposta varsolo per l'esecuzione del builtin che lo fa comportare in modo simile a quando viene eseguito un comando esterno.
Il commandcomando può essere usato per rimuovere l' attributo speciale di quei builtin speciali . Ciò che POSIX ha trascurato però è che per evale i .builtin, ciò significherebbe che le shell dovrebbero implementare uno stack variabile (anche se non specifica i comandi di limitazione dell'ambito localo typeset), perché potresti fare:
a=0; a=1 command eval 'a=2 command eval echo \$a; echo $a'; echo $a
O anche:
a=1 command eval myfunction
con myfunctionessere una funzione che utilizza o imposta $ae potenzialmente chiama command eval.
Questo è stato davvero un aspetto negativo perché ksh(su cui si basa principalmente la specifica) non lo ha implementato (e AT&T kshe zshancora non lo fanno), ma oggigiorno, tranne quei due, la maggior parte delle shell lo implementano. Il comportamento varia tra le conchiglie anche se in cose come:
a=0; a=1 command eval a=2; echo "$a"
anche se. L'utilizzo localsu shell che lo supportano è un modo più affidabile per implementare l'ambito locale.
IFS=: command eval …impostaIFSsolo per la durata dieval, come richiesto da POSIX, in trattino, pdksh e bash, ma non in ksh 93u. È insolito vedere ksh come il dispari-non conforme-one-out.