En algunas conchas (incluidas bash
):
IFS=: command eval 'p=($PATH)'
(con bash
, puede omitir command
si no está en la emulación sh / POSIX). Pero tenga en cuenta que cuando usa variables sin comillas, generalmente también necesita hacerlo set -f
, y no hay un alcance local para eso en la mayoría de los shells.
Con zsh, puedes hacer:
(){ local IFS=:; p=($=PATH); }
$=PATH
es forzar la división de palabras que no se realiza de forma predeterminada en zsh
( no se hace globbing en la expansión de variables, por lo que no es necesario a set -f
menos que sea en emulación sh).
(){...}
(o function {...}
) se denominan funciones anónimas y generalmente se utilizan para establecer un ámbito local. con otros shells que admiten el alcance local en funciones, podría hacer algo similar con:
e() { eval "$@"; }
e 'local IFS=:; p=($PATH)'
Para implementar un ámbito local para variables y opciones en shells POSIX, también puede usar las funciones proporcionadas en https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh . Entonces puedes usarlo como:
. /path/to/locvar.sh
var=3,2,2
call eval 'locvar IFS; locopt -f; IFS=,; set -- $var; a=$1 b=$2 c=$3'
(por cierto, no es válido dividir de $PATH
esa manera arriba excepto en zsh
como en otros shells, IFS es delimitador de campo, no separador de campo).
IFS=$'\n' a=($str)
Son solo dos tareas, una tras otra igual a=1 b=2
.
Una nota de explicación sobre var=value cmd
:
En:
var=value cmd arg
Los ejecuta shell /path/to/cmd
en un nuevo proceso y pases cmd
y arg
en argv[]
y var=value
en envp[]
. Eso no es realmente una asignación de variables, sino más variables de entorno que pasan al comando ejecutado . En el shell Bourne o Korn, con set -k
, incluso puedes escribirlo cmd var=value arg
.
Ahora, eso no se aplica a las funciones o funciones incorporadas que no se ejecutan . En el shell Bourne, en var=value some-builtin
, var
termina siendo establecido después, al igual que con var=value
solo. Eso significa, por ejemplo, que el comportamiento de var=value echo foo
(que no es útil) varía dependiendo de si echo
está incorporado o no.
POSIX y / o ksh
cambió eso en el sentido de que el comportamiento de Bourne solo ocurre para una categoría de incorporados llamados incorporados especiales . eval
es una construcción especial, read
no lo es. Para el builtin no especial, se var=value builtin
establece var
solo para la ejecución del builtin que hace que se comporte de manera similar a cuando se ejecuta un comando externo.
El command
comando se puede utilizar para eliminar el atributo especial de esas incorporaciones especiales . Lo POSIX se pasa por alto es que aunque para los eval
y .
las órdenes internas, eso significaría que las conchas tendría que implementar una pila variable (aunque no especifica los local
o typeset
alcance comandos de limitación), ya que podría hacer:
a=0; a=1 command eval 'a=2 command eval echo \$a; echo $a'; echo $a
O incluso:
a=1 command eval myfunction
con myfunction
ser una función usando o configurando $a
y potencialmente llamando command eval
.
Eso fue realmente un descuido porque ksh
(en el que se basa principalmente la especificación) no lo implementó (y AT&T ksh
y zsh
aún no lo hace), pero hoy en día, excepto esos dos, la mayoría de los shells lo implementan. El comportamiento varía entre los caparazones, aunque en cosas como:
a=0; a=1 command eval a=2; echo "$a"
aunque. El uso local
de shells que lo soportan es una forma más confiable de implementar el alcance local.
IFS=: command eval …
estableceIFS
solo para la duración deeval
, según lo dispuesto por POSIX, en guión, pdksh y bash, pero no en ksh 93u. Es inusual ver a ksh como un extraño que no cumple.