Estoy escribiendo un script de shell que debería ser algo seguro, es decir, no pasa datos seguros a través de parámetros de comandos y preferiblemente no usa archivos temporales. ¿Cómo puedo pasar una variable al stdin de un comando? O, si no es posible, ¿cómo utilizar correctamente los archivos temporales para dicha tarea?
105
$PATH
? Para quecat
pueda ser reemplazado/bin/cat "$@" | tee /attacker/can/read/this/file
Respuestas:
Algo tan simple como:
fuente
echo "$blah"
es mejor.blah=-n
,blah=-e
... usaprintf
en su lugar. unix.stackexchange.com/questions/65803/…printf '%s\n' "$blah"
? Con ese cambio (evitando las muchas trampas enecho
la especificación, que la excelente respuesta de Stephane entra en detalle en ¿Por qué esprintf
mejor queecho
? En Unix y Linux , o que la sección de USO DE APLICACIONES de laecho
especificación toca más brevemente) es un perfecto respuesta razonable.Pasar un valor a
stdin
en bash es tan simple como:¡Siempre asegúrese de poner comillas alrededor de las expresiones variables!
fuente
<<<
se garantiza que estas cadenas estén disponibles, no están en la base POSIX, hasta donde yo sé. Funcionarán como se espera, siempre y cuando solo los ejecutebash
. Solo lo menciono, porque OP dijeron 'shell', no específicamente 'bash'. Aunque etiquetó la pregunta conbash
... así que obviamente esta es una respuesta aceptable.echo
método debido a la creación de una tubería. El comando herestring será procesado por completobash
, aunque en esta situación (como se indicó) es mejor que sepa que funcionará en su bash, de lo contrario, cualquier mensaje de error producido como resultado de no admitir herestrings también filtraría dicha información.echo
es una función de. No hay tubería allí, ¿verdad? Es Unix, pero no puede ser tanto Unix .printf '%s\n' "$var"
produce los mismos resultados queecho "$var"
pero no se romperá si, por ejemplovar=-en
, y ni siquiera requiere bash.Tenga en cuenta que las
echo "$var" | command
operaciones ' significan que la entrada estándar se limita a las líneas repetidas. Si también desea que el terminal esté conectado, deberá ser más elegante:Esto significa que la (s) primera (s) línea (s) serán el contenido de
$var
pero el resto provendrá decat
leer su entrada estándar. Si el comando no hace nada demasiado sofisticado (intente activar la edición de la línea de comandos o ejecutarlo como lovim
hace), estará bien. De lo contrario, debe ser realmente elegante, creo queexpect
es probable que uno de sus derivados sea apropiado.Las notaciones de la línea de comando son prácticamente idénticas, pero el segundo punto y coma es necesario con las llaves, mientras que no lo es con los paréntesis.
fuente
( echo "$LIST"; cat - ) | sed 1q
esto funciona para mí pero necesito presionar ctrl d cuando ejecuto este script?cat -
continúa para leer desde el teclado hasta que EOF o interrupción, por lo que necesita para contarlo EOF mediante la tipificación de control-D.cat
nada si no desea una entrada de terminal, como en la primera línea. O puede usarcat
para listar un archivo. O ... Si desea que el comando lea la entrada del terminal, debe informarle cuando haya llegado al final de la entrada. O podrías usar( echo "$var"; sed /quit/q - ) | command
; esto continúa hasta que escriba una línea que contenga 'salir'. Puede ser infinitamente inventivo con la forma en que lo maneja. Cuidado con la vieja leyenda urbana de un programa que dejó de funcionar cuando los usuarios empezaron a trabajar con Ecuador. Tecleaban el nombre de la capital, Quito, y el programa terminaba.echo "$LIST" | sed 1q | ...
? Todo depende de lo que se trate. La<<EOF
notación debería requerir un EOF al comienzo de una línea por sí solo en algún lugar del archivo. No lo usaría, creo, pero todavía no estoy seguro de lo que está tratando de lograr. Un simpleecho "$LIST" | command
oecho $LIST | command
probablemente será suficiente en la práctica (y es importante que conozca el significado de la diferencia entre los dos).Me gustó la respuesta de Martin, pero tiene algunos problemas dependiendo de lo que haya en la variable. Esta
es mejor si la variable contiene "o!
fuente
foo1=-; foo2='"'; foo3=\!; cat<<<"$foo1"; cat<<<"$foo2"; cat<<<"$foo3"
funciona bien para mí. ¿Qué hacen exactamente los tres"
? AFAIK, solo está anteponiendo y agregando una cadena vacía.El
cat
no es realmente necesario, pero ayuda a estructurar el código mejor y le permite usar más comandos paréntesis como entrada a su comando.fuente
$passwd
Según la respuesta de Martin, hay una función de bash llamada Here Strings (que en sí misma es una variante de la función Here Documents más ampliamente compatible ).
http://www.gnu.org/software/bash/manual/bashref.html#Here-Strings
Tenga en cuenta que Here Strings parecería ser solo bash, por lo que, para una mejor portabilidad, probablemente estaría mejor con la función Here Documents original, según la respuesta de PoltoS:
O una variante más simple de lo anterior:
Puede omitir
(
y)
, a menos que desee que esto se redirija más a otros comandos.fuente
Esta forma robusta y portátil ya ha aparecido en los comentarios. Debería ser una respuesta independiente.
o
Notas:
echo
, las razones están aquí: ¿Por qué esprintf
mejor queecho
?printf "$var"
Está Mal. El primer argumento es el formato donde se interpretan%s
o gustan varias secuencias . Para pasar la variable correctamente, no debe interpretarse como formato.\n
Por lo general, las variables no contienen nuevas líneas finales. El primer comando (con
%s
) pasa la variable tal como está. Sin embargo, las herramientas que funcionan con texto pueden ignorar o quejarse de una línea incompleta (consulte ¿Por qué los archivos de texto deben terminar con una nueva línea? ). Por lo tanto, es posible que desee el último comando (con%s\n
) que agrega un carácter de nueva línea al contenido de la variable. Hechos no obvios:<<<"$var" my_cmd
) agrega una nueva línea.my_cmd
, incluso si la variable está vacía o no está definida.fuente
Prueba esto:
fuente
ps -u
cuando se está ejecutando echo?echo
es una función incorporada, por lo que no hay ningún proceso para mostrar en psecho "$variable"
es mejor.Solo haz:
Si la var no contiene espacios, las comillas pueden omitirse.
Si usa bash, también puede hacer:
Evite el uso de echo sin -n porque canalizará la variable con un salto de línea adicional al final.
fuente
%s
, printf no imprimirá nada.my_var="%s"; printf "$my_var";
- ¿Quizás intentarloprintf "%s" "$my_var" | my_cmd
?