Uso práctico de la opción `set -k` en bash

16

¿Cuándo usamos la set -kopción en bash?

El manual de referencia de Bash dice:

Todos los argumentos en forma de declaraciones de asignación se colocan en el entorno de un comando, no solo los que preceden al nombre del comando.

Entiendo lo que hace la opción, pero no podía imaginar cuándo la necesitamos.

MS.Kim
fuente
Percepción correcta. El -knos permite ejecutar scripts de shell de 30 años sin la necesidad de refactorizarlos. Pase variables de entorno temporales utilizando la sintaxis de prefijo en su lugar:var1=x var2=y command ...
Henk Langeveld

Respuestas:

14

Básicamente, puede usarlo en cualquier momento que desee "inyectar" las variables de entorno pasadas a un script de shell (como argumentos) como si estuvieran establecidas en el entorno a través de export, pero sin tener que tener que residir permanentemente en exportla lista antes de ejecutar comandos .

NOTA: También existe la forma larga del -kinterruptor, set -o keyword.

Ejemplo

$ cat cmd1.bash 
#!/bin/bash

echo $VARCMD

Ahora si yo set -k:

$ set -k; ./cmd1.bash VARCMD="hi"; set +k
hi

Pero si solo ejecutara el script anterior:

$ ./cmd1.bash 

$

¿Qué hace la exportación?

$ help export
...
Marks each NAME for automatic export to the environment of subsequently
executed commands.  If VALUE is supplied, assign VALUE before exporting.
...

Entonces, si tuviéramos que agregar export | grep VARa nuestro script así:

$ cat cmd2.bash 
#!/bin/bash

echo $VARCMD
export | grep VAR

Y volvimos a ejecutar nuestras pruebas anteriores:

$ set -k; ./cmd2.bash VARCMD="hi"; set +k
hi
declare -x VARCMD="hi"

Pero sin set -k:

$ ./cmd2.bash 

$

Entonces, set -knos permite exportar temporalmente variables en masa.

Otro ejemplo

$ cat cmd3.bash 
#!/bin/bash

echo $VARCMD1
echo $VARCMD2
export | grep VAR

Cuando establecemos múltiples variables, todas se exportan:

$ set -k; ./cmd3.bash VARCMD1="hi" VARCMD2="bye"; set +k
hi
bye
declare -x VARCMD1="hi"
declare -x VARCMD2="bye"

Entonces, ¿solo está inyectando todas las variables de entorno?

No -kestá haciendo algo muy explícito aquí. Solo exporta variables que se incluyeron en la línea de comando cuando se ejecutó un comando.

Ejemplo

Digamos que configuro esta variable:

$ VARCMD1="hi"

Ahora cuando ejecutamos el mismo comando omitiendo VARCMD1="hi":

$  set -k; ./cmd3.bash VARCMD2="bye"; set +k

bye
declare -x VARCMD2="bye"

¿Pero por qué existe esto?

Encontré esta fuente que explica un poco sobre esta característica, titulada: "Cadenas de asignación de parámetros de palabras clave". NOTA: La URL de origen utiliza una dirección IP, por lo que no puedo vincularla directamente aquí en SE.

http://140.120.7.21/OpenSystem2/SoftwareTools/node16.html

Al programar en cualquier lenguaje, la variable y su paso de valor es fundamental para escribir código confiable. Además de los tipos de variables enteras y de matriz, todas las demás variables de shell aceptan cadenas como sus valores. Cuando hablamos del lenguaje de programación de shell, para ser coherentes, preferimos la frase "parámetro de palabra clave". Aquí hay algunos puntos a tener en cuenta al asignar valores a los parámetros de palabras clave:

  • Para evitar cualquier efecto inesperado, coloque siempre la subcadena de asignación de parámetros delante de una cadena de comando.

    En el shell B, los valores asignados de los parámetros de palabras clave se almacenarán en variables de shell (locales). En bash y ksh, las cadenas de asignación de parámetros de palabras clave que preceden el comando no se almacenarán en las variables de shell. Solo afectan el subproceso inmediato bifurcado para ejecutar el comando actual. Una línea de cadenas de asignación de parámetros de palabras clave solo se almacena en las variables de shell (locales). Las cadenas de asignación de parámetros de palabras clave también pueden aparecer como argumentos para los comandos incorporados alias, declarar, componer, exportar, solo lectura y local. [Sección 3.4 del Manual de referencia de Bash]

  • Las cadenas de asignación de parámetros de palabras clave se tratarán como argumentos para que se ejecute el comando, si se colocan después del nombre del comando.

  • Los parámetros de palabras clave pueden ser manipulados por el comando set.
slm
fuente
En este enlace, ss64.com/bash/set.html , set -kporque han dado -o keywordademás de la -kopción. ¿Eso significa algo?
Ramesh
@Ramesh: set -o keywordes la forma larga de set -k. Ver help set | grep -- '-k'.
slm
ah ok Estuve rascándome la cabeza durante mucho tiempo tratando de entender por qué hay 2 opciones. Como de costumbre respuesta perfecta :)
Ramesh
44
./cmd.bash VARCMD=hinecesita set -kque funcione exactamente como lo VARCMD=hi ./cmd.bashhace sin el set -k. Supongo que la pregunta específica del OP se refiere a la necesidad de bash para admitir el ./cmd.bash VARCMD=hiformulario
iruvar
@ 1_CR - buen punto. Creo que tiene que ver más con el estilo que con cualquier otra cosa, aunque veré si puedo encontrar una fuente real.
slm
8

Cualquier uso práctico de set -kes probable que sea solo un estilo personal. Algunos, tal vez aquellos a quienes les gustan los lenguajes de programación que ofrecen la capacidad de usar argumentos de palabras clave en llamadas a funciones, o aquellas pocas personas a las que les gusta la ddsintaxis del comando, pueden preferir

set -k
...
comando var 1 = val 1 var 2 = val 2

a

var 1 = val 1 var 2 = comando
 val 2

La razón real por la que existe la opción en algunos shells se explica en la justificación del comando set en el estándar POSIX :

The following set flags were omitted intentionally with the following rationale:

The -k flag was originally added by the author of the Bourne shell to make it easier
for users of pre-release versions of the shell. In early versions of the Bourne shell
the construct
    set name=value
had to be used to assign values to shell variables.
Mark Plotnick
fuente