/ bin / sh fuente de stdin (de otro programa) no archivo


14

Un poco complicado para nombrar esto ...

Básicamente tengo un programa que cuando se ejecuta imprime en STDOUT un conjunto de variables de shell:

$ ./settings
SETTING_ONE="this is setting one"
SETTING_TWO="This is the second setting"
ANOTHER_SETTING="This is another setting".

Quiero ejecutar esto desde un script de shell como si se estuviera evaluando el STDOUT source.

Me gustaría hacer algo como ...

source `./settings`

... pero por supuesto eso no funciona.

Sé que podría hacer:

./settings >/tmp/file
source /tmp/file

pero realmente no quiero hacer eso.

¿Alguna pista?

Respuestas:


16

Puedes usar eval:

eval "$(./settings)"

eval "`./settings`"

Lo siento, debería haber mencionado, es / bin / sh no bash. $ () no funciona. He actualizado la pregunta.
Majenko

@ Matt: Bueno, sh es bash en la mayoría de los sistemas. A menos que, por supuesto, se refiera a las versiones recientes de Ubuntu, donde se ha reemplazado con guión.
Hola71

@ Matt: en ese caso, los backticks deberían funcionar. Pero también debería agregar la versión exacta de sh: podría ser un enlace simbólico a dash, ash, busybox ... No he visto una copia de "la verdadera 'sh'" en vivo.
user1686

1
@Matt: Entonces tienes un ... sistema interesante allí. Especialmente porque casi todas las variaciones "sh" son compatibles $( ), comenzando con el shell de Almquist en 4.3BSD , y también es POSIX. (Nota: sin discutir, solo curioso.)
usuario1686

$ () existe, simplemente no funciona así en esta circunstancia. FreeBSD 8.2's / bin / sh
Majenko

15

En los sistemas donde /dev/fdestá disponible, bash admite la sustitución de procesos:

source <(./settings)

Aquí, <( )se expandirá a una ruta asignada automáticamente bajo la /dev/fd/...cual ./settingsse puede leer la salida de .


1
En el manual de bash, esto se llama "sustitución de proceso".
Glenn Jackman

6
declare `./settings`

O por supuesto ...

export `./settings`

Pruébalo por supuesto ...

export `echo -e "asdf=test\nqwerty=dvorak"` ; echo $asdf $qwerty

Manejo de espacios en blanco:

eval export `./settings`

¡Ajá, el exporttruco funciona! Gracias
Majenko

Ahora, ¿cómo puedo manejar espacios en un valor?
Majenko

@Matt: no puedo usar backticks en los comentarios, así que por favor vea la respuesta editada.
user1686

@grawity: Sí, puedes ...a backtick --> ` <-- and here's another one --> ` <--
Hola71

2

source /dev/stdin < ./settings

Sin embargo, creo que / dev / stdin es una cosa única de Linux.


que intenta obtener el contenido de la configuración. Incluso con './settings' falla con './settings': Ambiguous ('= backtick)
Majenko

/dev/stdintambién funciona en BSD y Cygwin.
user1686

1
Usando |, sin embargo, está no va a funcionar (al menos no exactamente), debido a que ambos lados de la tubería son subprocesos separados, de modo comandos de origen no afectarían a la shell actual.
user1686

1
editado para reflejar eso.
LawrenceC

1
Me gusta este /dev/stdintruco, pero lo que hace su respuesta es, de hecho, equivalente a un plano source ./settingssin ejecutarlo. Se podría utilizar un documento interno para superar esto: source /dev/stdin <<EOF \n $(./settings) \n EOF.
tlwhitec

0

Quería proporcionar otra perspectiva aquí, ya que las otras respuestas crean archivos y no extraen directamente de stdin. Tengo algunas compilaciones que necesitan enviar información del entorno preparada a varios scripts. Lo que estoy haciendo es preparar un montón de asignaciones de variables compatibles con Bash en una cadena:

Var1="Foo"
Var2="Bar"
Var3="Baz"

Cuando me estoy preparando para ejecutar el script, codifico base64 la cadena multilínea anterior y la canalizo en mi script de shell:

echo base64EncodedParameters | build.sh

En build.sh leí de stdin, decodifica base64 y evalué el resultado.

params=""
while read line; do params="${params}${line}"; done
eval `echo $params | base64 -D`

echo "Hello ${Var1} ${Var2}"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.