Saltar al contenido

¿Pasar todas las variables de un script de shell a otro?

Nuestro equipo de expertos despúes de ciertos días de investigación y recopilar de información, encontramos la respuesta, deseamos que todo este artículo sea de gran utilidad para tu proyecto.

Solución:

Tienes básicamente dos opciones:

  1. Haga de la variable una variable de entorno (export TESTVARIABLE) antes de ejecutar el segundo script.
  2. Obtenga el segundo script, es decir . test2.sh y se ejecutará en el mismo shell. Esto le permitiría compartir variables más complejas como matrices fácilmente, pero también significa que el otro script podría modificar variables en el shell de origen.

ACTUALIZAR:

Usar export para establecer una variable de entorno, puede utilizar una variable existente:

A=10
# ...
export A

Esto debería funcionar en ambos bash y sh. bash también permite combinarlo así:

export A=10

Esto también funciona en mish (que resulta ser bash, puedes usar echo $SHELL verificar). Pero no creo que esté garantizado que funcione en todos sh, así que es mejor ir a lo seguro y separarlos.

Cualquier variable que exporte de esta manera será visible en los scripts que ejecute, por ejemplo:

ceniza:

#!/bin/sh

MESSAGE="hello"
export MESSAGE
./b.sh

b.sh:

#!/bin/sh

echo "The message is: $MESSAGE"

Luego:

$ ./a.sh
The message is: hello

El hecho de que ambos sean scripts de shell también es incidental. Las variables de entorno se pueden pasar a cualquier proceso que ejecute, por ejemplo, si usamos Python en su lugar, podría verse así:

ceniza:

#!/bin/sh

MESSAGE="hello"
export MESSAGE
./b.py

b.py:

#!/usr/bin/python

import os

print 'The message is:', os.environ['MESSAGE']

Abastecimiento:

En su lugar, podríamos obtener algo así:

ceniza:

#!/bin/sh

MESSAGE="hello"

. ./b.sh

b.sh:

#!/bin/sh

echo "The message is: $MESSAGE"

Luego:

$ ./a.sh
The message is: hello

Esto más o menos “importa” el contenido de b.sh directamente y lo ejecuta en el mismo caparazón. Observe que no tuvimos que exportar la variable para acceder a ella. Esto comparte implícitamente todas las variables que tiene, así como también permite que el otro script agregue / elimine / modifique variables en el shell. Por supuesto, en este modelo, ambos guiones deben ser del mismo idioma (sh o bash). Para dar un ejemplo de cómo podríamos pasar mensajes de un lado a otro:

ceniza:

#!/bin/sh

MESSAGE="hello"

. ./b.sh

echo "[A] The message is: $MESSAGE"

b.sh:

#!/bin/sh

echo "[B] The message is: $MESSAGE"

MESSAGE="goodbye"

Luego:

$ ./a.sh
[B] The message is: hello
[A] The message is: goodbye

Esto funciona igualmente bien en bash. También facilita compartir datos más complejos que no podría expresar como una variable de entorno (al menos sin un poco de trabajo pesado de su parte), como matrices o matrices asociativas.

Error fatal dio una posibilidad sencilla: ¡obtenga su segundo script! Si le preocupa que este segundo script pueda alterar algunas de sus valiosas variables, siempre puede obtenerlo en una subcapa:

( . ./test2.sh )

Los paréntesis harán que la fuente ocurra en un subshell, de modo que el shell padre no verá las modificaciones. test2.sh podría realizar.


Hay otra posibilidad a la que definitivamente se debe hacer referencia aquí: use set -a.

Desde el POSIX set referencia:

-a: Cuando esta opción está activada, exportar attribute se establecerá para cada variable a la que se realiza una asignación; consulte el volumen de Definiciones básicas de IEEE Std 1003.1-2001, Sección 4.21, Asignación de variables. Si la asignación precede al nombre de una utilidad en un comando, el exportar attribute no persistirá en el entorno de ejecución actual después de que se complete la utilidad, con la excepción de que antes de una de las utilidades incorporadas especiales exportar attribute para persistir después de que se haya completado la incorporación. Si la asignación no precede al nombre de una utilidad en el comando, o si la asignación es el resultado de la operación del getopts o leer servicios públicos, la exportación attribute persistirá hasta que se elimine la variable.

Del manual de Bash:

-a: Marque las variables y funciones que se modifican o crean para exportar al entorno de comandos posteriores.

Entonces en tu caso:

set -a
TESTVARIABLE=hellohelloheloo
# ...
# Here put all the variables that will be marked for export
# and that will be available from within test2 (and all other commands).
# If test2 modifies the variables, the modifications will never be
# seen in the present script!
set +a

./test2.sh

 # Here, even if test2 modifies TESTVARIABLE, you'll still have
 # TESTVARIABLE=hellohelloheloo

Observe que las especificaciones solo especifican que con set -a la variable es marcado para exportación. Es decir:

set -a
a=b
set +a
a=c
bash -c 'echo "$a"'

se hará eco c y no una línea vacía ni b (es decir, set +a no desmarca para exportación, ni “guarda” el valor de la asignación solo para el entorno exportado). Este es, por supuesto, el comportamiento más natural.

Conclusión: usando set -a/set +a puede ser menos tedioso que exportar manualmente todas las variables. Es superior a obtener el segundo script, ya que funcionará con cualquier comando, no solo con los escritos en el mismo lenguaje de shell.

En realidad, hay una manera más fácil que exportar y desarmar o abastecer nuevamente (al menos en bash, siempre que esté de acuerdo con pasar las variables de entorno manualmente):

deja que una.sh sea

#!/bin/bash
secret="winkle my tinkle"
echo Yo, lemme tell you "$secret", b.sh!
Message=$secret ./b.sh

y b.sh sea

#!/bin/bash
echo I heard "$Message", yo

La salida observada es

[[email protected] prueba]$ ./a.sh
¡Déjame decirte “winkle my tinkle”, b.sh!
Escuché “winkle my tinkle”, yo

La magia está en la última línea de a.sh, dónde Message, solo por la duración de la invocación de ./b.sh, se establece en el valor de secret de a.sh. Básicamente, es un poco como parámetros / argumentos con nombre. Sin embargo, más que eso, incluso funciona para variables como $DISPLAY, que controla en qué servidor X se inicia una aplicación.

Recuerde, la longitud de la lista de variables de entorno no es infinita. En mi sistema con un kernel relativamente vainilla, xargs --show-limits me dice que el tamaño máximo del búfer de argumentos es 2094486 bytes. Teóricamente, está utilizando scripts de shell incorrectamente si sus datos son más grandes que eso (¿canalizaciones, alguien?)

Recuerda algo, que te permitimos valorar esta sección si atinaste tu enigma en el momento justo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *