2011-01-23 7 views
58

Estoy escribiendo un script de shell que debe ser algo seguro, es decir, no pasa datos seguros a través de parámetros de comandos y preferiblemente no utiliza archivos temporales. ¿Cómo puedo pasar una variable al stdin de un comando? O, si no es posible, ¿cómo usar correctamente los archivos temporales para dicha tarea?¿Cómo pasar el valor de una variable al stdin de un comando?

+0

¿Puede un atacante cambiar '$ PATH'? Para que 'cat' se pueda reemplazar por'/bin/cat "$ @" | tee/atacante/can/read/this/file' – 12431234123412341234123

Respuesta

47

Algo tan simple como:

echo "$blah" | my_cmd 
+6

Tenga cuidado con los espacios en su variable: 'echo" $ blah '' es mejor. –

+0

@Jonathan: Ese es un buen punto. Respuesta actualizada en consecuencia ... –

+3

Funcionará incluso cuando hay un '" 'en' $ blah'? –

5

Prueba esto:

echo "$variable" | command 
+0

pero no aparecería el contenido $ variable en, por ejemplo, la salida de 'ps -u' cuando echo se está ejecutando? –

+2

no, no lo hará. 'echo' está integrado, por lo que no hay ningún proceso para mostrar en ps – unbeli

+1

Tenga cuidado con los espacios en su variable:' echo "$ variable" 'es mejor. –

11
(cat <<END 
$passwd 
END 
) | command 

El cat no es realmente necesario, pero ayuda a estructurar el código mejor y le permite utilizar más comandos entre paréntesis como entrada a su comando.

+0

Pero este método le permite pasar varias líneas a su comando y también permite espacios en '$ passwd' – PoltoS

+0

Esta es la mejor respuesta hasta el momento que no pierde contenidos variables para canalizar o procesar la inspección. – user2688272

117

Pasando un valor de entrada estándar es tan simple como:

your-command <<< "$your_variable" 

controlar siempre que ponga comillas alrededor expresiones variables!

+30

Herestrings '<<<' no son gua para que estén disponibles, no están en la base POSIX, hasta donde yo sé. Funcionarán como se espera, siempre y cuando solo los ejecutes en 'bash'. Solo lo menciono, porque OP dijo 'shell' no específicamente 'bash'. Aunque marcó la pregunta con 'bash' ... por lo que esta sigue siendo obviamente una respuesta aceptable. – TechZilla

+0

Si bien este puede ser el caso, es probable que la información sensible se filtre más fácilmente si se usa el método 'echo' debido a la creación de una tubería. El comando herestring será procesado completamente por 'bash', aunque en esta situación (como se señaló) es mejor que sepas que funcionará en tu bash, de lo contrario cualquier mensaje de error producido como resultado de no soportar herestrings también podría filtrar dicha información . –

+0

@StevenLu Espera, 'echo' es un built-in. No hay tubería allí, ¿verdad? Es Unix, pero no puede ser * tanto Unix *. –

15

Tenga en cuenta que las operaciones 'echo "$var" | command significan que la entrada estándar está limitada a la (s) línea (s) repetidas. Si también desea que el terminal para conectarse, a continuación, tendrá que ser más elegante:

{ echo "$var"; cat - ; } | command 

(echo "$var"; cat - ) | command 

Esto significa que la primera línea (s) será el contenido de $var pero el resto provendrá de la lectura de su cat entrada estándar. Si el comando no hace nada demasiado elegante (intente activar la edición de línea de comandos, o ejecutar como vim) entonces estará bien. De lo contrario, debe ser realmente elegante: creo que expect o uno de sus derivados es probable que sea apropiado.

Las anotaciones de línea de comando son prácticamente idénticas, pero el segundo punto y coma es necesario con las llaves, mientras que no está entre paréntesis.

+0

' (echo " $ LIST "; cat -) | sed 1q' esto funciona para mí pero necesito presionar ctrl d cuando ejecuto este script? –

+0

Sí, el' cat -' continúa leyendo desde el teclado hasta EOF o interrumpe, por lo que necesita para decirle EOF escribiendo control-D. –

+0

¿Hay alguna manera de evitar las necesidades de EOF cat –

5

De acuerdo con la respuesta de Martin, no es una característica de bash llamado Aquí Cuerdas (que en sí es una variante de los Aquí Documentos apoyado más ampliamente de función).

http://www.gnu.org/software/bash/manual/bashref.html#Here-Strings

3.6.7 Aquí Cuerdas

una variante de aquí documentos, el formato es:

<<< word 

La palabra se expande y se suministra al sistema en su estándar entrada.

Tenga en cuenta que esta medida serían Cuerdas para ser bash-solamente, así que, para mejorar la portabilidad, que probablemente sería mejor con el original Aquí cuentan con documentos, de acuerdo con la respuesta de PoltoS:

(cat <<EOF 
$variable 
EOF 
) | cmd 

o bien, una variante más simple de lo anterior:

(cmd <<EOF 
$variable 
EOF 
) 

puede omitir ( y ), a menos que usted quiere tener este redirigido su vez en otros comandos.

11

Me gustó la respuesta de Martin, pero tiene algunos problemas según lo que hay en la variable. ! Este

your-command <<< """$your_variable""" 

es mejor si la variable contiene "o

+2

¿Pero por qué? Además, no puedo reproducir ningún problema: 'foo1 = -; foo2 = '"'; foo3 = \ !; cat <<<" $ foo1 "; cat <<<" $ foo2 "; cat <<<" $ foo3 "' funciona bien para mí. ¿Qué hacen exactamente los tres '? '¿hacer? AFAIK usted está anteponiendo y anexando una cadena vacía. – phk

+0

Pruebe algo real. Al igual que tu comando es ssh somehost. y tu variable es un script de shell –

0

Sólo hacer:

printf "$my_var" | my_cmd 

Si la var no contiene espacios a continuación, las cotizaciones pueden ser omitidos
Si se utiliza. bash entonces usted también puede hacer:

echo -n "$my_var" | my_cmd 

Evitar usi ng echo sin -n porque canalizará el vraiable con un salto de línea adicional al final.

Cuestiones relacionadas