Automatizar la entrada de texto desde un script bash sin usar EOF

Automatizar la entrada de texto desde un script bash sin usar EOF

Estoy ejecutando Ubuntu Linux. Supongamos que hay un programa llamado myprogram. Este programa solicita al usuario información; específicamente, el usuario debe escribir un número entero cuando se le solicite y presionar Enter. Me gustaría automatizar este proceso usando un script bash. En particular, me gustaría ejecutar myprogram, digamos, 100 veces (usando un contador ique va de 1a 100). En cada ejecución de myprogram, me gustaría ingresar el valor actual de icuando se me solicite.

(Por cierto, myprogramtoma opciones/interruptores -options, todos los cuales serán constantes y, por lo tanto, se especificarán dentro del script bash).

Un esqueleto incompleto de este script bash podría ser:

#!/bin/bash
for i in {1..100}
do
   myprogram -options
done

Ahora me gustaría modificar el código anterior para que ise ingrese el valor actual de cuando el programa lo solicite. ¿Cuál es la mejor manera de hacer esto?

El sitio web del software que estoy usando sugiereusando <<EOFal final de la myprogram -optionslínea. Creo que esto le dice a bash que busque en el "final del archivo" la entrada que va a utilizar. Pero ¿qué pasa si no quiero colocar la entrada en elfindel archivo? ¿Qué pasa si quisiera ponerlo inmediatamente después de <<o <?

La razón es que las cosas se complicarán más. Por ejemplo, puedo introducir un contador de números enteros jque cambie de alguna manera no lineal ni secuencial. Luego me gustaría introducir el valor actual de jto myprogramen cada iteración, pero el valor de jpuede cambiar entre la llamada a myprogram -optionsy el final del archivo EOF.

¿Tienes alguna sugerencia?

Respuesta1

Para casi todos los programas, ambos echo $i | myprogram -optionsy myprogram -options <<<$ideberían funcionar, alimentando el programa $ia través de la entrada estándar.

<fooutilizará el contenido del archivo denominado foostdin.

<<fooutilizará el texto entre eso y una línea que consta únicamente de foocomo entrada estándar. Esto es unaquí documento(heredoc), como dijo Gilles; EOFen realidad no significa el final del archivo, es solo un delineador heredoc común (en este ejemplo usamos "foo" en su lugar).

<<<fooutilizará la cadena "foo" como entrada estándar. También puede especificar una variable $fooy el shell usará su contenido como entrada estándar, como mostré arriba. Esto se llama unheredero, ya que utiliza una cadena corta en contraste con un bloque completo, como en un heredoc. Las cadenas Herestrings funcionan en bash, pero no en /bin/sh.

Respuesta2

La sintaxis recomendada por este sitio web se denominaaquí documento. La entrada al archivo del programa comienza inmediatamente debajo de la línea que contiene <<EOFy no termina al final del script, sino en una línea que contiene exactamente el texto EOF(tenga cuidado de no tener espacios en blanco adicionales). Por cierto, puedes usar cualquier marcador final que no contenga ningún carácter especial del shell: EOFno es una palabra clave, es meramente tradicional.

#!/bin/bash
for i in {1..100}
do
   myprogram -options <<EOF
$i
EOF
   for j in {1..42}; do
     myprogram2 <<EOF
$i
$j
EOF
   done
done

Respuesta3

Aquí los documentos mencionados anteriormente por Kevin y Gilles, o una simple tubería funcionarán en muchos casos.

Para situaciones más complicadas, es posible que desee consultar Expect o algo similar (por ejemplo, el módulo Expect::Simple CPAN es una implementación de Perl muy fácil de usar). Personalmente, prefiero el módulo Perl (Expect en sí es tcl), pero existen implementaciones para muchos lenguajes de scripting comunes. Incluso es posible escribir unmuyImplementación primitiva de la idea en sh o bash usando while y read.

La idea general de Expect y herramientas similares es esperar una cadena o patrón específico en la salida de un programa y luego alimentarlo con la entrada que desee.

Un ejemplo de uso común es automatizar el inicio de sesión, "esperando" (es decir, esperando) la cadena "ogin:", envíe el nombre de inicio de sesión, luego espere la cadena "palabra:" y envíe la contraseña.

Una última opción, si tiene la fuente de myprogram, es simplemente modificarla para tomar la entrada que desea darle como opción de línea de comando. Esto podría requerir un poco más de trabajo por adelantado, pero será mucho menos irritante que jugar con Expect o canalizar datos a un programa que no fue diseñado para usarse de esa manera.

... y no olvides enviar tu parche a myprogram nuevamente :) Incluso si no les gusta la forma en que lo has codificado, es posible que les guste la idea lo suficiente como para agregar la función ellos mismos. Los desarrolladores upstream tienden a apreciar a las personas que se esfuerzan y contribuyen en lugar de exigir o quejarse.

información relacionada