Ich arbeite an der Automatisierung einer Wartungsroutine, bei der ein Skript gestartet und gestoppt wird, das in einer Bildschirmsitzung ausgeführt wird. Mein Ansatz besteht darin, die Bildschirmsitzung zu beenden, sie dann neu zu starten und den Befehl innerhalb eines Skripts auszuführen, wobei ich die Funktionen zum Erstellen eines Bildschirms und zum Übergeben eines Befehls verwende, ohne eine Verbindung zum Bildschirm herstellen zu müssen.
Ich habe damit jedoch Schwierigkeiten. Ich kann den Bildschirm korrekt erstellen, ohne ihn mit anzuhängen screen -d -m -S screen_name
. Wenn ich jedoch einen Befehl basierend auf Folgendem ausführe:
screen -S screen_name-X stuff "command 1"'echo -ne '\015''"command 2"'echo -ne '\015''
wobei echo -ne '\015' mit Backticks statt einfachen Anführungszeichen umschlossen ist. Dies soll simulieren, dass der Benutzer die Eingabetaste drückt, da die von mir verwendeten Befehle in ein Verzeichnis wechseln und ein dort befindliches Skript ausführen. Dieser Befehl funktioniert, aber nur, wenn der Bildschirm nach seiner Erstellung angehängt wurde. Da ich versuche, den Prozess der Bildschirmerstellung und der Ausführung der darin enthaltenen Befehle zu automatisieren, möchte ich das Anhängen und Abhängen innerhalb eines Skripts vermeiden. Ich werde den Vorschlag ausprobieren, ein Shell-Skript zu erstellen, das die Befehle enthält, die ich innerhalb des Bildschirms ausführen und entsprechend meinen Ergebnissen bearbeiten muss.
Gibt es eine Möglichkeit, einen Bildschirm zu erstellen und einen Befehl innerhalb des Bildschirms auszuführen, entweder in einem Befehl oder ohne nach dem Erstellen, aber vor der Ausführung des Befehls eine Verbindung zum Bildschirm herstellen zu müssen?
Dank im Voraus.
**Update – nachdem ich den Vorschlag ausprobiert habe, die Befehle, die ich ausführen muss, in ein Shell-Skript einzufügen, konnte ich erfolgreich einen Bildschirm erstellen und die Befehle innerhalb des Bildschirms ausführen, aber ich erhalte das Verhalten, dass der Bildschirm ebenfalls geschlossen wird, wenn das Skript nicht mehr ausgeführt wird. Dies sollte kein Problem sein, da es sich bei dem Skript um ein Protokollierungsskript handelt, das nur mit dem Wissen des Systemadministrators oder durch das Skript, das ich zu entwickeln versuche, beendet werden sollte. Es wäre jedoch vorzuziehen, den Bildschirm so einzurichten, dass der Bildschirm nicht verschwindet, wenn das Skript beendet wird. Ist es möglich, dieses Verhalten zu erreichen? **
Antwort1
Ich glaube, Sie stoßen möglicherweise auf mehrere Probleme.
Wenn der Befehl beendet wird, bevor Sie ihn erneut anhängen, verschwindet der Bildschirm. Sie können dies mit folgendem demonstrieren:
screen -d -m ls -l
Der Befehl wird ausgeführt ls -l
, aber screen -list
nicht angezeigt, da der Bildschirmprozess beendet ist.
Ich habe auch keine Ahnung, was Sie mit diesem \015-Zeug vorhaben. Vielleicht würde es helfen, Ihre Frage zu aktualisieren, denn ich glaube, Sie versuchen, mehrere Befehle in einer Bildschirmsitzung auszuführen. Das sollte so einfach sein wie:
screen -d -m bash -c "command1 ; command2 ; command3"
Wenn diese häufig verwendet werden, sollten Sie vielleicht ein Shell-Skript erstellen, das nur diese Befehle ausführt, und dann ein einfacheres verwenden:
screen -d -m /path/to/script.sh
Antwort2
Starten Sie einen getrennten Bildschirm
screen -dmS <screen name>
Befehl im zuvor erstellten, abgetrennten Bildschirm ausführen
screen -S <screen name> -X stuff '<CMD>\n'
Ja, Sie müssen das Eingabezeichen eingeben, um den Befehl zu senden. Andernfalls wird nur die Zeichenfolge zum Bildschirm hinzugefügt.
Antwort3
Das hat bei mir funktioniert, ohne -c
ging es nicht
screen -d -m bash -c "command1; command2; command3"
Antwort4
Eine Möglichkeit zum Testen vorheriger Antworten per Kopieren und Einfügen ist:
# 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
Das erwartete Ergebnis sollte ungefähr wie folgt aussehen:
No Sockets found in /var/run/screen/S-yourusernamehere.
(Das bedeutet, dass zuvor keine Bildschirmsitzung erstellt wurde)
real 0m0.002s
user 0m0.000s
sys 0m0.000s
(Dies ist die Zeit, die zum Erstellen und Trennen des Bildschirms benötigt wird. Fast augenblicklich.)
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.
(Diese Ausgabe zeigt die verfügbaren Bildschirmsitzungen. Mit dem letzten Befehl erstellt.)
sleep 20; cat /tmp/h
(Dies cat
zeigt den Hostnamen, der innerhalb von GNU-Screen ausgeführt wird)