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 quecatpueda ser reemplazado/bin/cat "$@" | tee /attacker/can/read/this/fileRespuestas:
Algo tan simple como:
fuente
echo "$blah"es mejor.blah=-n,blah=-e... usaprintfen su lugar. unix.stackexchange.com/questions/65803/…printf '%s\n' "$blah"? Con ese cambio (evitando las muchas trampas enechola especificación, que la excelente respuesta de Stephane entra en detalle en ¿Por qué esprintfmejor queecho? En Unix y Linux , o que la sección de USO DE APLICACIONES de laechoespecificación toca más brevemente) es un perfecto respuesta razonable.Pasar un valor a
stdinen 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.echomé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.echoes 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" | commandoperaciones ' 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
$varpero el resto provendrá decatleer 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 lovimhace), estará bien. De lo contrario, debe ser realmente elegante, creo queexpectes 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 1qesto 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.catnada si no desea una entrada de terminal, como en la primera línea. O puede usarcatpara 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<<EOFnotació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" | commandoecho $LIST | commandprobablemente 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
catno 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
$passwdSegú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é esprintfmejor queecho?printf "$var"Está Mal. El primer argumento es el formato donde se interpretan%so gustan varias secuencias . Para pasar la variable correctamente, no debe interpretarse como formato.\nPor 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 -ucuando se está ejecutando echo?echoes 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?