L'idea di base è che i VAR=VALUE some-commandset VARper VALUEper l'esecuzione di some-commandquando some-commandè un comando esterno, e non ottiene più fantasia di quello. Se combini questa intuizione con una certa conoscenza di come funziona una shell, nella maggior parte dei casi dovresti trovare la risposta giusta. Il riferimento POSIX è "Comandi semplici" nel capitolo "Linguaggio di comando Shell" .
Se some-commandè un comando esterno , VAR=VALUE some-commandequivale a env VAR=VALUE some-command. VARviene esportato nell'ambiente di some-command, e il suo valore (o mancanza di valore) nella shell non cambia.
Se some-commandè una funzione , allora VAR=VALUE some-commandequivale a VAR=VALUE; some-command, ovvero l'assegnazione rimane attiva dopo che la funzione è tornata e la variabile non viene esportata nell'ambiente. La ragione di ciò ha a che fare con il design della shell Bourne (e successivamente con la compatibilità con le versioni precedenti): non aveva la possibilità di salvare e ripristinare valori variabili attorno all'esecuzione di una funzione. Non esportare la variabile ha senso poiché una funzione viene eseguita nella shell stessa. Tuttavia, ksh (inclusi ATT ksh93 e pdksh / mksh), bash e zsh implementano il comportamento più utile dove VARviene impostato solo durante l'esecuzione della funzione (viene anche esportato). In ksh , questo viene fatto se la funzione è definita con la sintassi kshfunction NAME …, non se è definito con la sintassi standard NAME (). In bash , questo viene fatto solo in modalità bash, non in modalità POSIX (se eseguito con POSIXLY_CORRECT=1). In zsh , questo viene fatto se l' posix_builtinsopzione non è impostata; questa opzione non è impostata per impostazione predefinita ma è attivata da emulate sho emulate ksh.
Se some-commandè incorporato, il comportamento dipende dal tipo di incorporato. I builtin speciali si comportano come funzioni. Gli incorporamenti speciali sono quelli che devono essere implementati all'interno della shell perché influenzano la shell di stato (ad es. Influenza il breakflusso di controllo, cdinfluenza la directory corrente, setinfluenza i parametri posizionali e le opzioni ...). Altri built-in sono integrati solo per prestazioni e praticità (principalmente - ad es. La funzione bash printf -vpuò essere implementata solo da un built-in) e si comportano come un comando esterno.
L'assegnazione avviene dopo l'espansione dell'alias, quindi se some-commandè un alias , espanderlo prima per trovare cosa succede.
Si noti che in tutti i casi, l'assegnazione viene eseguita dopo l'analisi della riga di comando, inclusa l'eventuale sostituzione di variabili sulla riga di comando stessa. Quindi var=a; var=b echo $varstampa a, perché $varviene valutato prima che l'incarico abbia luogo. E quindi IFS=. printf "%s\n" $varutilizza il vecchio IFSvalore per dividere $var.
Ho coperto tutti i tipi di comandi, ma c'è ancora un caso: quando non c'è nessun comando da eseguire , cioè se il comando è costituito solo da assegnazioni (e possibilmente reindirizzamenti). In tal caso, l'incarico rimane al suo posto . VAR=VALUE OTHERVAR=OTHERVALUEè equivalente a VAR=VALUE; OTHERVAR=OTHERVALUE. Quindi IFS=. arr=($var), IFSrimane impostato su .. Poiché è possibile utilizzare $IFSnell'assegnazione arrcon l'aspettativa che abbia già il suo nuovo valore, ha senso che il nuovo valore di IFSvenga utilizzato per l'espansione di $var.
In sintesi, è possibile utilizzare solo IFSper la suddivisione temporanea dei campi:
- avviando una nuova shell o una subshell (ad es.
third=$(IFS=.; set -f; set -- $var; echo "$3")è un modo complicato di fare third=${var#*.*.}tranne che si comportano diversamente quando il valore di varcontiene meno di due .caratteri);
- in ksh, con
IFS=. some-functiondove some-functionè definito con la sintassi ksh function some-function …;
- in bash e zsh,
IFS=. some-functionpurché operino in modalità nativa anziché in modalità compatibilità.
IFSrimane impostato su." Eek. Dopo aver letto la prima parte, questo ha senso, ma prima di pubblicare questa Q, non me lo sarei aspettato.