La idea básica es que los VAR=VALUE some-commandconjuntos VARa VALUEla ejecución de some-commandcuando some-commandes un comando externo, y que no puede ser más elegante que eso. Si combina esta intuición con algún conocimiento de cómo funciona un shell, debe encontrar la respuesta correcta en la mayoría de los casos. La referencia POSIX es "Comandos simples" en el capítulo "Lenguaje de comandos de Shell" .
Si some-commandes un comando externo , VAR=VALUE some-commandes equivalente a env VAR=VALUE some-command. VARse exporta en el entorno de some-command, y su valor (o falta de valor) en el shell no cambia.
Si some-commandes una función , entonces VAR=VALUE some-commandes equivalente a VAR=VALUE; some-command, es decir, la asignación permanece en su lugar después de que la función ha regresado y la variable no se exporta al entorno. La razón de esto tiene que ver con el diseño del shell Bourne (y posteriormente con la compatibilidad con versiones anteriores): no tenía facilidad para guardar y restaurar valores variables en torno a la ejecución de una función. No exportar la variable tiene sentido ya que una función se ejecuta en el propio shell. Sin embargo, ksh (incluidos ATT ksh93 y pdksh / mksh), bash y zsh implementan el comportamiento más útil donde VARse establece solo durante la ejecución de la función (también se exporta). En ksh , esto se hace si la función se define con la sintaxis kshfunction NAME …, no si se define con la sintaxis estándar NAME (). En bash , esto se hace solo en modo bash, no en modo POSIX (cuando se ejecuta con POSIXLY_CORRECT=1). En zsh , esto se hace si la posix_builtinsopción no está configurada; esta opción no está configurada de manera predeterminada pero está activada por emulate sho emulate ksh.
Si se some-commandtrata de una construcción, el comportamiento depende del tipo de construcción. Los componentes especiales especiales se comportan como funciones. Las incorporaciones especiales son las que deben implementarse dentro del shell porque afectan el shell de estado (por ejemplo break, cdafecta el flujo de control, afecta el directorio actual, setafecta los parámetros de posición y las opciones ...). Otras funciones incorporadas están integradas solo por rendimiento y conveniencia (principalmente, por ejemplo, la función bash printf -vsolo puede implementarse mediante una función integrada), y se comportan como un comando externo.
La asignación se lleva a cabo después de la expansión del alias, por lo que si some-commandes un alias , amplíelo primero para encontrar qué sucede.
Tenga en cuenta que en todos los casos, la asignación se realiza después de analizar la línea de comando, incluida cualquier sustitución de variable en la línea de comando. Entonces var=a; var=b echo $varimprime a, porque $varse evalúa antes de que se realice la asignación. Y así IFS=. printf "%s\n" $varusa el IFSvalor anterior para dividir $var.
He cubierto todos los tipos de comandos, pero hay un caso más: cuando no hay un comando para ejecutar , es decir, si el comando consiste solo en asignaciones (y posiblemente redireccionamientos). En ese caso, la asignación permanece en su lugar . VAR=VALUE OTHERVAR=OTHERVALUEes equivalente a VAR=VALUE; OTHERVAR=OTHERVALUE. Entonces IFS=. arr=($var), después , IFSpermanece establecido en .. Como puede usar $IFSen la asignación arrcon la expectativa de que ya tiene su nuevo valor, tiene sentido que el nuevo valor de IFSse use para la expansión de $var.
En resumen, puede usar solo IFSpara la división temporal de campos:
- iniciando un nuevo shell o un subshell (por ejemplo,
third=$(IFS=.; set -f; set -- $var; echo "$3")es una forma complicada de hacerlo, third=${var#*.*.}excepto que se comportan de manera diferente cuando el valor de varcontiene menos de dos .caracteres);
- en ksh, con
IFS=. some-functiondonde some-functionse define con la sintaxis ksh function some-function …;
- en bash y zsh,
IFS=. some-functionsiempre y cuando estén operando en modo nativo en oposición al modo de compatibilidad.
IFSpermanece establecido en." Eek. Después de leer la primera parte, eso tiene sentido, pero antes de publicar esta Q, no hubiera esperado eso.