Crear pantalla y ejecutar comando sin adjuntar

29

Estoy trabajando en la automatización de una rutina de mantenimiento que implica iniciar y detener un script que se ejecuta en una sesión de pantalla. Mi enfoque es matar la sesión de la pantalla, y luego reiniciarla y ejecutar el comando desde un script usando las habilidades para crear una pantalla y pasar un comando sin necesidad de adjuntarlo a la pantalla.

Sin embargo, estoy teniendo dificultades con esto. Puedo crear la pantalla correctamente sin que se adjunte usando screen -d -m -S screen_name. Sin embargo, si ejecuto un comando basado en:

screen -S screen_name-X stuff "command 1"'echo -ne '\015''"command 2"'echo -ne '\015''

con el eco -ne '\ 015' envuelto con comillas invertidas en lugar de comillas simples. Es para simular al usuario presionando la tecla Intro ya que los comandos que uso se mueven a un directorio y ejecutan un script ubicado allí. Este comando funciona, pero solo si la pantalla se ha adjuntado una vez que se ha creado. Como estoy tratando de automatizar el proceso de creación de la pantalla y ejecutar los comandos dentro de ella, me gustaría evitar tener que adjuntar y desconectar dentro de un script. Intentaré la sugerencia de crear un script de shell que contenga los comandos que necesito ejecutar dentro de la pantalla y editar de acuerdo con mis resultados.

¿Hay alguna manera de crear una pantalla y ejecutar un comando dentro de la pantalla, ya sea en un comando o sin tener que adjuntarlo a la pantalla después de crear, pero antes de ejecutar el comando?

Gracias por adelantado.

** Actualización: después de probar la sugerencia de colocar los comandos que necesito ejecutar dentro de un script de shell, pude crear con éxito una pantalla y ejecutar los comandos desde dentro de la pantalla, pero obtengo el comportamiento que cuando el script deja de ejecutarse la pantalla también se cierra. Esto no debería ser un problema, ya que el script es un script de registro que solo debe detenerse con el conocimiento del administrador del sistema o mediante el script que estoy tratando de desarrollar, sin embargo, sería preferible configurar la pantalla de tal manera que la pantalla no desaparece si se detiene el script. ¿Es posible lograr este comportamiento? ** **

codificador de café
fuente
1
Me encontré con este mismo problema y encontré una solución en superuser.com para cualquier persona que se encuentre con este problema superuser.com/questions/342463/…
Dan Herbert
Para mantener la pantalla abierta, puede usar algo como: screen bash -c 'echo "test"; / bin / bash '
gwyn
1
Para su problema de cierre automático, puede usar un especial .screenrcque contenga la línea zombie kr, que mantendrá abierta una ventana terminada, y puede presionar kpara cerrar el winodw, o rejecutar el comando en la ventana nuevamente. Tengo esto para mi .screenrc predeterminado.
Martin C.

Respuestas:

18

Creo que puede encontrarse con varios problemas.

Si el comando finaliza antes de volver a adjuntarlo, la pantalla desaparecerá. Puede demostrar esto usando:

screen -d -m ls -l

Ejecutará el ls -lcomando, pero screen -listno lo mostrará cuando el proceso de la pantalla haya finalizado.

Tampoco tengo idea de lo que estás tratando de hacer con estas cosas. Quizás actualizar su pregunta ayudaría, ya que lo que creo que está tratando de hacer es ejecutar múltiples comandos en una sesión de pantalla. Esto debería ser tan simple como:

screen -d -m bash -c "command1 ; command2 ; command3"

Si se usan mucho, tal vez debería hacer un script de shell que ejecute solo estos comandos, luego use uno más simple:

screen -d -m /path/to/script.sh
Michael Graff
fuente
¿Hay alguna manera de obtener un comportamiento similar sin que la pantalla se separe de inmediato? Digamos que quiero comenzar una sesión ssh y luego separarme inmediatamente después; screen -d -m sshse separará en la solicitud de contraseña antes de que se realice la sesión.
estrella brillante
Esto no funciona para mi. Reemplazar hte "commandN" con varios programas de ejecución prolongada hace que no aparezca nada screen -list. Además, esto no nombra la pantalla como el OP está tratando de hacer.
Cerin
Estaba buscando ejecutar un programa de Python usando este método. Traté de crear un script sh para ejecutarlo, pero no vi la pantalla en la lista. En su lugar, usé screen -d -m python EventGenerator.py, lo que funcionó muy bien
Dan Ciborowski - MSFT
1
Probablemente debería ser en bash -c "commands"lugar debash "commands"
marcovtwout
Tienes razón, tiene que haber -c.
Xdg
9

Iniciar una pantalla separada

screen -dmS <screen name>

Ejecutar comando en pantalla separada previamente creada

screen -S <screen name> -X stuff '<CMD>\n'

Sí, debe escribir el símbolo Intro para enviar el comando o, de lo contrario, simplemente agregará la cadena a la pantalla.

http://osdir.com/ml/gnu.screen/2003-09/msg00029.html

Yogesh
fuente
1
¿Qué es 'cosas'?
Nadav B
stuffen realidad es un comando que copia y pega otro comando en una sesión de pantalla: stuff [string] Rellena la cadena en el búfer de entrada de la ventana actual. Esto es como el comando "pegar" pero con mucho menos sobrecarga. Sin un parámetro, la pantalla solicitará que se llene una cadena. No puede pegar buffers grandes con el comando "cosas". Es más útil para las combinaciones de teclas. Ver también "bindkey". [Citado de theterminallife.com/sending-commands-into-a-screen-session/]
alisa
2

He encontrado este problema antes, era un error con la implementación de cygwin.

Lo que hice fue crear un ".screenrc_detaching" con solo el siguiente comando

#detach
detach 

y luego inicie la pantalla con

screen -c ~/loginScripts/tempScreenrc/.screenrc_detaching

Luego tiene su sesión de pantalla y ya se ha adjuntado y desconectado y puede enviarle comandos.

Fácil! :PAGS

PiersyP
fuente
2

Esto hizo el trabajo para mí, sin que -cno funcionara

screen -d -m bash -c "command1; command2; command3"

Mazilu88
fuente
1

Una forma de copiar y pegar para probar las respuestas anteriores es:

 # No sessions:
screen -ls

 # Returns immediately:
time screen -dmS screen_descritive_session_name  bash -c 'sleep 20; hostname >> /tmp/h'

 # New session present:
screen -ls

 # File with return of command was created :)
sleep 20; cat /tmp/h

El resultado esperado debería ser similar a:

No Sockets found in /var/run/screen/S-yourusernamehere.

(Eso significa que no se creó previamente ninguna sesión de pantalla)

real    0m0.002s
user    0m0.000s
sys     0m0.000s

(Es el tiempo dedicado a crear una pantalla y desprenderse de ella. Casi instantáneo).

There is a screen on:
    20318.screen_descritive_session_name    (20/08/2018 16:29:35)   (Detached)
1 Socket in /var/run/screen/S-yourusernamehere.

(Esta salida muestra sesiones de pantalla disponibles. Creado con el último comando).

sleep 20; cat /tmp/h

(Esto catmuestra el nombre de host ejecutado dentro de gnu-screen)

Enrique S. Filiage
fuente
¿Y cuál es el resultado de tales pruebas?
Pierre.Vriens
Tienes razón, no había ejemplo. Añadiré.
Enrique S. Filiage
¡mucho mejor! merci! +1
Pierre.Vriens
0
screen -S test -d -m -- sh -c 'ls; exec $SHELL'
Nadav B
fuente