Importar variables en un script de shell desde otro sin ejecutar el script de shell referido

Importar variables en un script de shell desde otro sin ejecutar el script de shell referido

Tengo 2 scripts de shell, file1.sh y file2.sh

archivo1.sh

#!/usr/bin/env bash 
export var1="/data/share"
export var2='password'
echo "Hello"

archivo2.sh

#!/usr/bin/env bash 
source file1.sh
echo $var1
echo $var2

Cuando ejecuto file2.sh, obtengo el siguiente resultado

Hello
/data/share
password

Pero mi resultado esperado es

/data/share
password

file1.sh se ejecuta cuando se hace referencia a file2.sh. ¿Cómo importo las variables solas en file2.sh sin ejecutar file1.sh?

Respuesta1

Hay tres opciones que uso cuando tengo un script bash que quiero que se comporte de manera diferente cuando se obtiene y cuando se ejecuta (o en otras palabras, tengo elementos de datos en un script a los que quiero acceder sin ejecutar ningún código en ese momento). tiempo). Los comentarios los tocaron hasta cierto punto.

opcion uno

Determinar cuándo se obtendrá y finalizar el "abastecimiento" en el momento adecuado.

Separe el guión en dos secciones, salga del guión cuando lo obtenga antes de llegar al segundo inferior

Cree una sección superior de script con definiciones (funciones/asignaciones de variables/etc.), pero sin ejecución directa de código.

Justo antes de que comience la sección del código ejecutable, coloque la lógica que saldrá del script si detecta que se está obteniendo. El siguiente segmento de código hará esto:


archivo1.sh

#!/usr/bin/env bash
export var1="/data/share"
export var2='password'    
# --- End Definitions Section ---    
# check if we are being sourced by another script or shell
[[ "${#BASH_SOURCE[@]}" -gt "1" ]] && { return 0; }
# --- Begin Code Execution Section ---
echo "Hello"
echo $var1
echo $var2 


archivo2.sh

#!/usr/bin/env bash 
source file1.sh
echo "$var1"
echo "$var2"


Salida de ejecutar ./file2.sh

$ ./file2.sh 
/data/share
password

Opción dos

Este normalmente sólo se usa en situaciones complejas y para este ejemplo en particular es excesivo. Creo una función en el archivo que quiero obtener y en esa función determino qué debería estar disponible para la persona que llama. En este caso son las dos variables exportadas. Normalmente uso este modo cuando tengo matrices asociativas, que de otro modo serían casi imposibles de manejar. Además, la persona que llama debe eliminar el archivo tmp; pero no lo hice en este caso:


archivo1.sh

#!/usr/bin/env bash 
export var1="/data/share"
export var2='password'
exportCfg() {
  tmpF=$(mktemp)
  declare -p var1 var2 > "$tmpF"
  echo "$tmpF"
}
if [ "$1" == "export" ]; then
  exportCfg;
  exit 0;
fi

echo "Hello"
echo $var1
echo $var2


archivo2.sh

#!/usr/bin/env bash 
source $(./file1.sh export)


echo "$var1"
echo "$var2"

El resultado de la ejecución de file2.sh es el mismo que el anterior

Opción 3

La última forma común en que manejo esto es simplemente con un archivo de biblioteca que solo contiene definiciones y no tiene código que se ejecute cuando se obtenga o se ejecute directamente. Esto es simplemente una cuestión de dividir su código. Tengo un grupo de 'libras' de bash que contienen funciones de uso frecuente y, por proyecto, generalmente configuro una pequeña biblioteca de origen para almacenar datos de configuración (constantes). Si esos datos incluyen matrices pobladas, también usaré una versión de la Opción 2.

Respuesta2

Si todas sus variables se exportan de la misma manera (exportar foo=barra), entonces puedes obtenerlos todos fácilmente usandointentocaracterística de sustitución de procesos:

source <(grep '^export .*=' file1.sh)

Extracto de la página de manual:

Sustitución de procesos La sustitución de procesos se admite en sistemas que admiten canalizaciones con nombre (FIFO) o el método /dev/fd para nombrar archivos abiertos. Toma la forma de <(lista) o >(lista). La lista de procesos se ejecuta con su entrada o salida conectada a un FIFO o algún archivo en /dev/fd. El nombre de este archivo se pasa como argumento al comando actual como resultado de la expansión. Si se utiliza el formulario >(lista), escribir en el archivo proporcionará información para la lista. Si se utiliza el formato <(lista), el archivo pasado como argumento debe leerse para obtener el resultado de la lista.

información relacionada