Führen Sie den Bildschirm (GNU) über das Skript aus

11

Ich möchte eine Anwendung innerhalb einer Bildschirmsitzung starten, jedoch über ein Skript.
Ohne Skript würde ich einfach den Bildschirm starten, dann N Fenster mit crtl-ac öffnen und Programme in jedem Fenster ausführen.

Ich habe folgendes versucht

screen -d -m -S test
screen -S test -X exec tail -f /var/log/messages
screen -S test -X screen
screen -S test -X exec tail -f /var/log/xinetd.log

Aber wenn ich anhänge, läuft der Sitzungsende nicht. Wenn ich die Sitzung direkt danach anhänge screen -d -m -S startupund screen -S startup -X exec tail -f /var/log/messagesvon einem anderen Terminal aus starte, funktioniert sie.

Habe ich etwas verpasst ?

Bearbeiten nach AlexD Antwort:

Eine halb funktionierende Lösung ist

screen -d -m -S test tail -f /var/log/messages
screen -S test -X screen tail -f /var/log/xinetd.log

Das Verketten des Bildschirmbefehls (der nach -X) mit dem Befehl funktioniert, während exec wahrscheinlich nicht, weil exec erwartet, dass ein aktuelles Fenster definiert wird, während es kein aktuelles gibt, wenn der Bildschirm getrennt wird. Vielen Dank an AlexD für diese Tipps.

Aber es gibt einen seltsamen Nebeneffekt: Wenn das Programm stoppt (wenn Sie die Bildschirmsitzung anhängen und den Schwanz drücken oder den Schwanz drücken oder schließen), wird das Bildschirmfenster geschlossen.
Das Verhalten ist also nicht dasselbe wie bei Crtl-A c und führt den Befehl aus.
Ein weiterer Nebeneffekt ist, dass Sie keine 2 Befehle verketten können

Radius
quelle
screen Beendet immer , wenn der Befehl, mit dem gestartet wurde, endet - dies ist eine normale Funktion des Tools :) ..so wenn Sie ausführen screen top, wenn Sie beenden top, screenwird auch beendet
warren
Ja, jetzt habe ich versucht, screen als deamon zu starten, dann exec zu verwenden und dann mit dem Befehl screen ein neues Fenster zu öffnen (eine Shell starten). Ich habe auch versucht, Bash zwischen Exec und Tail oder zwischen Screen und Tell
Radius

Antworten:

14

Mit diesem screen -S test -X screen commandBefehl müssen Sie Ihrer Daemon-Sitzung Fenster hinzufügen, jedoch nicht aus den von Ihnen angegebenen Gründen. Es funktioniert, weil -X einen Bildschirmbefehl und keinen Shell-Befehl verwendet und der Bildschirmbefehl zum Erstellen eines Fensters verwirrenderweise als Bildschirm bezeichnet wird. Es gibt keinen Befehl exec exec. Es gibt auch keine Verkettung, es sei denn, Sie erstellen Ihren Befehl mithilfe von Shell-Skripten (wie folgt :) screen -S script -X screen sh -c 'command1; command2;'.

Das Aufrufen screen -S test -X screenohne Befehl ist nutzlos, da der Standardbefehl eine Shell ist. Sobald Sie eine Shell erstellt haben, haben Sie keine nicht interaktive (und nicht verschlagene) Möglichkeit, Befehle in dieser Shell auszuführen. Es ist besser, den Befehl ohne interaktive Shell selbst auszuführen. Ein Nebeneffekt ist, dass das Bildschirmfenster beim Beenden des Befehls kein Kind mehr hat und geschlossen wird.

Jetzt können Sie den Bildschirm auffordern, das Fenster nach dem Beenden des Befehls trotzdem offen zu halten. Verwenden Sie den zombieBildschirmbefehl, um dies zu aktivieren. Ihre Sequenz sieht aus wie:

screen -d -m -S script
screen -S script -X zombie qr
screen -S script -X screen tail -f /var/log/messages
screen -S script -X screen tail -f /var/log/xinetd.log

Interaktiv wieder anbringen:

screen -S script -r

Und schließlich können Sie diese -X-Befehle stattdessen als screenrc-Skript umschreiben.

Screenrc:

zombie qr
screen tail -f /var/log/messages
screen tail -f /var/log/xinetd.log

Skript:

screen -d -m -S script -c screenrc
Tobu
quelle
Ja, ich weiß, dass -X einen Bildschirmbefehl ausführt, das, was ich meine, als ich "Verkettung des Bildschirmbefehls (der nach -X)" sagte (Ok, es ist überhaupt nicht klar), aber es gibt einen Bildschirmausführungsbefehl, schauen Sie den Mann an Seite, aber wie Sie sagten, gibt es keine Möglichkeit, es im nicht interaktiven Modus wie gewünscht zum Laufen zu bringen. Wie auch immer, mit AlexD-Lösung und Ihrem Zombie-Befehl füge ich hinzu, was ich will! Vielen Dank
Radius
@Tobu: +200 für die Erwähnung von Zombies! Ich hätte es in diesem schrecklichen Handbuch letztendlich nie bemerkt!
Reben
6

Wenn Sie den gleichen Effekt wie Ctrl-A cdann wünschen , sollten Sie screenanstelle von exec:

screen -S test -X screen tail -f / var / log / messages
Bildschirm -S Test -X Bildschirm
screen -S test -X screen tail -f /var/log/xinetd.log

Sie können Ihre obigen Befehle auch in eine $HOME/.screenrc-younameitDatei (ohne screen -S test -XPräfix) verschieben und starten, screen -c $HOME/.screenrc-younameitwenn Sie eine bestimmte Bildschirmsitzung erstellen möchten.

AlexD
quelle
Die Strg-A-Taste befindet sich in meiner dritten Zeile. Ich denke, exec funktioniert nicht, da exec den Befehl in den aktuellen Fenstern ausführt, die möglicherweise nicht definiert sind, wenn der Bildschirm getrennt wird. Ihr Workaround-Verkettungsbildschirm und der Befehl sind nett, ich hätte es versuchen sollen! Ich werde eine Antwort zu mir selbst hinzufügen, weil Ihre Antwort die Sitzungserstellung fehlt und eine nutzlose Zeile (2., Überspringen von 1 Fenster) hat
Radius
Tatsächlich funktioniert es nicht wie erwartet, die Fenster werden geschlossen, sobald das Programm beendet wird. Wenn Sie Bildschirm-Test -X Bildschirm ls machen, wird das Fenster geschlossen und Sie werden nie das Ergebnis sehen
Radius
1

ist die Verwendung von Byobu eine Option?

Sirex
quelle
Ich habe es einfach versucht, ich sehe nicht, wie es helfen könnte, aber wenn Sie eine funktionierende Lösung mit byobu haben, könnte es in Ordnung sein, ich bevorzuge lieber eine Lösung nur für den Bildschirm, aber die Verwendung eines Add-Ons ist besser als keine Lösung zu haben!
Radius
1

Ich habe heute Abend dasselbe gemacht, ich wollte den Bildschirm mit mehreren vorgeöffneten Dateien öffnen. Es hat eine Weile gedauert, bis ich das alles herausgefunden habe, aber ich habe mir endlich Folgendes ausgedacht, das ziemlich gut zu funktionieren scheint:


#1/bin/sh 
screen -d -m -S CS140 
screen -S CS140 -X screen -t thread.c 
screen -p 1 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/thread.c\015"'
screen -S CS140 -X screen -t thread.h 
screen -p 2 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/thread.h\015"'
screen -S CS140 -X screen -t palloc.c 
screen -p 3 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/palloc.c\015"'
screen -S CS140 -X screen -t intr-stubs.h 
screen -p 4 -S CS140 -X eval 'stuff "vim cs140-ps2/src/threads/intr-stubs.h\015"'
screen -S CS140 -X screen -t pagedir.c 
screen -p 5 -S CS140 -X eval 'stuff "vim cs140-ps2/src/userprog/pagedir.c\015"'
screen -r -d CS140 

Dadurch werden sechs verschiedene Bildschirme erstellt, wobei die Bildschirme 1 bis 5 verschiedene Dateien geöffnet haben. Ich kenne nicht alle Einzelheiten, aber 'Zeug' sagt dem Bildschirm im Wesentlichen, dass der folgende zitierte Text kein Bildschirmbefehl ist. Das 'eval' evakuiert dann alles, was in den Zitaten enthalten ist. Ohne dies screen -p 4 -S CS140 -X stuff "vim cs140-ps2/src/threads/intr-stubs.h\015" leitet der zitierte Text einfach weiter, ohne ihn auszuführen. Eval liest '\ 015' als Zeilenumbruch und führt somit den vorhergehenden Text aus.

In Bezug auf andere Details screen -p 1 -S CS140 -X CMD weist die Shell an, die 'CMD' an das erste Fenster der Bildschirmsitzung mit dem Namen 'CS140' zu senden.

Ich hoffe, das hilft!

DevonH
quelle