Sospecho que esta es la parte de la secuencia que te está atrapando:
Las palabras que no son asignaciones variables o redirecciones se expanden (ver Expansiones de Shell). Si queda alguna palabra después de la expansión, la primera palabra se toma como el nombre del comando y las palabras restantes son los argumentos
Eso es del manual de referencia de Bash en la sección sobre Expansión de comandos simples.
En el cmd=bash
ejemplo, no se establecen variables de entorno, y bash procesa la línea de comandos a través de la expansión de parámetros, dejando bash -c "echo hi"
.
En el prefix=hello=hi
ejemplo, nuevamente no hay asignaciones variables en la primera pasada, por lo que el procesamiento continúa con la expansión de parámetros, lo que resulta en una primera palabra de hello=hi
.
Una vez que se han procesado las asignaciones de variables, no se vuelven a procesar durante la ejecución del comando.
Vea el procesamiento y sus resultados en set -x
:
$ prefix=hello=hi
+ prefix=hello=hi
$ $prefix bash -c 'echo $hello'
+ hello=hi bash -c 'echo $hello'
-bash: hello=hi: command not found
$ hello=42 bash -c 'echo $hello'
+ hello=42
+ bash -c 'echo $hello'
42
Para una variación más segura de "expansión variable" -como- "variables de entorno" que eval
, considere la sugerencia de wjandrea deenv
:
prefix=hello=hi
env "$prefix" bash -c 'echo "$hello"'
hi
No es estrictamente una asignación de variable de línea de comandos, ya que estamos utilizando la env
función principal de la utilidad de asignar variables de entorno a un comando, pero cumple el mismo objetivo. La $prefix
variable se expande durante el procesamiento de la línea de comandos, proporcionando el nombre = valor a env
quién se la pasa bash
.
env
lugar deeval
cuál IIRC es más seguro, pero más lento.