
Estoy en mis primeros pasos escribiendo un script de shell programado. El objetivo es escribir un script de copia de seguridad sencillo para un servidor de Minecraft. El servidor se ejecuta con su propio nombre.pantalla.
Supongo que si mi guión contiene algo como
screen -S $(screen_name) -p 0 -X stuff "save-all^M"
el comando del servidor tardará algún tiempo. Mi pregunta es: ¿el script continuará inmediatamente o esperará hasta que finalice el comando dentro de la pantalla a la que se accede? Si regresa inmediatamente, ¿cómo puedo esperar? (en este caso, el save-all
comando guarda el mundo actual. El siguiente paso sería copiar los archivos en una carpeta de respaldo, por lo que obviamente quiero esperar hasta que el mundo se guarde correctamente). ?
Respuesta1
No. El screen -X stuff
comando volverá inmediatamente, porque esno cuentaque se le pide que ejecute un comando en primer lugar, más aún cuando ese comando está completo; todo lo que hace es inyectar pulsaciones de teclas (razón por la cual tuvo que agregarlas ^M
manualmente). Tan pronto como se envía la entrada tty falsa, el comando regresa y el script continúa.
En general, como emulador de terminal, la pantalla no sabe qué está sucediendo exactamente en una ventana de terminal específica; no hay nada que pueda delimitar un indicador de shell (o cualquier otro indicador de consola interactivo) de la salida normal.
(Esto no es fundamentalmente imposible: algunos emuladores de terminal permiten que el shell genere marcadores de "inicio/fin de salida" y de "inicio/fin rápido", por ejemploCódigo VSinyectará una configuración especial en Bash para lograr exactamente eso, pero requiere soporte del emulador de terminalycooperación de todos los programas que mostrarían un mensaje de entrada, y ni Screen ni Minecraft lo harán actualmente).
Por otro lado, su secuencia de comandos puede resultar más fácil porque solo trata con un único programa, lo que significa que solo necesita esperar unaespecíficomensaje que aparezca, no cualquier mensaje en general. Podría implementar esto teniendo un bucle que consultaría a Screen el "contenido" del búfer actual usando -X hardcopy
, y si la última línea de ese búfer esnoEl mensaje de Minecraft todavía, duerme 1 segundo y repite.
Esto es similar a cómo expect
funciona el programa: se puede escribir un script Expect para automatizar varios tipos de entradas interactivas, pero el núcleo de dicho script es siempre un conjunto de expect "this"
y expect "that"
, es decir, saber de antemano que algún texto específico es un "mensaje". " y esperando ese mensaje de texto.
[...]
expect "Password:" { send "$password\r" }
expect ">" { send "enable\r" }
expect "Password:" { send "$enablepwd\r" }
expect "#" { send "show run\r" }
¿Qué hacen otros scripts de administración de Minecraft (comoeste proyecto, que recientemente cambió de Screen a tmux) parece ser 1) enviar ciegamente "guardar todo" y "detener" a la vez, 2) esperar a que el servidor procese los comandos del bot hasta que salga por sí solo. Es decir, en lugar de esperar a quedominiopara completar, esperan elresultadode ese comando.
Del mismo modo, si desea esperar a queahorrarpara finalizar, no necesita esperar el comando "guardar todo"; en su lugar, puede inotifywait
esperar hasta que el servidor haya terminado de escribir un archivo específico. Esto puede ser algo complicado de hacer correctamente (normalmente necesitarías usar "coproc" para iniciar inotifywaitantesemitir el comando para que no te pierdas el evento), pero como guardar es probable que demore un poco, esprobablementeestá bien hacerlo después.
echo "waiting..."
inotifywait -q -e close_write /path/to/game
echo "probably done!"
Algunos programas crean deliberadamente un archivo específico al final, para que otras herramientas puedan esperar a que aparezca:
echo "waiting..."
until [ -e /path/to/marker_file ]; do sleep 1; done
echo "marker file showed up"