Wie starte ich eine GUI-App sauber über das Terminal?

78

Einige GUI-Apps werden über die Terminal-Befehlszeile sauber gestartet, andere jedoch nicht, und das Terminal wartet darauf, dass die App beendet wird. Selbst dann "geben" manche die Befehlszeile nicht frei.

Das mysteriöse kaufmännische Und- &Suffix scheint das Terminal dazu zu veranlassen, den Prozess in den Hintergrund zu stellen (aber ich bin nicht sicher, was dort passiert).

Gibt es eine Möglichkeit, eine App über das Terminal zu starten, so dass es keinen "Hang on" -Effekt gibt, genau wie das Starten von etwas über Alt+ F2?

Ich möchte die Kommandozeile sofort wieder zur Verfügung haben, ohne dass noch etwas im Hintergrund ist und im Terminal gedruckt wird.

Peter.O
quelle
Auf Wunsch von htorque habe ich seine von Ihnen akzeptierte Antwort gelöscht. Könnten Sie bitte eine andere Antwort auswählen (Sie müssen zuerst htorques abwählen - sollte am unteren Rand der Seite in rot lauern)
Oli
1
Die Methode, mit einem bereits laufenden Programm umzugehen (wie durch con-f-use beschrieben), ist in dieser Situation gut, aber da meine Hauptfrage das saubere Starten ohne Terminal-Unordnung war , habe ich zugestimmt screen(von Oli erwähnt) und RobinJ). Ich bin beeindruckt von seiner Fähigkeit; nachdem darüber zu lesen und zu versuchen , es aus ... Es erfordert nur die Eingabe von: screen -d -m gedit(oder screen geditdann Ctrl+a dzu lösen) ... und ich habe immer noch vollen Zugang zum Terminal nach Ansicht des gedit (für Nachrichten usw. Warnung) jederzeit über , screen -rauch wenn ich habe in der Zwischenzeit das ursprüngliche Terminalfenster geschlossen ...
Peter.O
Übrigens werden einige der Dinge, die Sie dem Terminal zuweisen, von der Shell ausgeführt, z. B. die Interpretation des &Befehlssuffix. Dies kann zur Verdeutlichung hilfreich sein: Was ist der Unterschied zwischen Terminal, Konsole, Shell und Befehlszeile?
wjandrea

Antworten:

17

In gedit's Fall lasse ich einfach eine Kopie die ganze Zeit offen. Solange eine vorhandene Kopie ausgeführt wird, geditwird gedit nicht beendet, wenn Sie Anrufe vom Terminal aus starten und dann das Terminal schließen.

Für andere Dinge würde das, was andere Leute gesagt haben, auch funktionieren. Ich bin ein Fan von nohup... Aber wenn Sie ein Terminal benötigen, das Sie abnehmen und dann wieder anbringen können, möchten Sie es sich ansehen screen.

  1. Führen Sie es in einem Terminal aus, und führen Sie dann etwas aus, das die Ausgabe ständig pusht. Ich benutze den Django-Entwicklungsserver aber irssioder watch uptimewäre sogar ein gutes Beispiel.
  2. Töte das Terminal und beginne ein neues.
  3. Lauf screen -rund BOOM, du bist wieder da.

screenist viel größer als das und Sie können es byobufür ein besseres Terminal-Erlebnis mit kombinieren . Lies herum.

Oli
quelle
Dies ist der erste wirkliche Einblick, den ich in Bezug auf die Funktionsweise von Bildschirmen hatte ... Danke für den Terminal-Tipp ...
Peter.O
Bildschirm ist nicht mehr verfügbar, aber tmux kann Bildschirm ersetzen. (tmux, um eine neue tmux-Sitzung zu starten, Strg + b, dann d drücken, um die Verbindung herzustellen, und tmux, um die Verbindung herzustellen)
Gman Smith,
84

Angenommen, geditdas Programm, das Sie ausführen möchten, ist nicht verbunden (auch bekannt als "disowned", "disentangled", "decoupled"). Es gibt verschiedene Möglichkeiten, je nachdem, was Sie genau tun möchten:

Programm läuft bereits

Verleugnen:

disown -hist der richtige Weg, wenn Sie dies mit einem bereits laufenden Programm tun möchten (dh wenn Sie es vergessen nohuphaben). Sie müssen es zuerst mit Ctrl+ stoppen Z. Dann können Sie mit bg [jobId](zB bg 1) in den Hintergrund stellen . Sie erhalten eine Liste der ausgeführten Jobs mit der Job-ID, die verwendet wird jobs. Danach können Sie es mit vom Terminal abkoppeln disown -h %[jobId]. Beispiel für eine Terminalsitzung:

$ gedit 
^Z
[1]+  Stopped                 gedit
$ jobs
[1]+  Stopped                 gedit
$ bg 1
[1]+ gedit &
$ disown -h %1
$ exit

Programm noch nicht gestartet

Nohup

nohupist nicht immer auf allen Maschinen vorhanden. Wenn Sie wissen, dass Sie vorab entkoppeln möchten, verwenden Sie:

nohup gedit &

Vielleicht möchten Sie die Shell - Ausgabe als auch und Ihr Programm eine Pseudo - Eingangsquelle umgeleitet werden , so: nohup ./myprogram > foo.out 2> bar.err < /dev/null &. Sie möchten die Ausgabe umleiten, um entweder nicht gestört zu werden oder um sie später zu verwenden. Die Null-Eingabe kann helfen, Fehler in ssh und so zu vermeiden.

Unterschale:

Sie können einen ähnlichen Effekt erzielen, indem Sie

$ (geany >/dev/null 2>&1 &)

Die eckigen Klammern öffnen eine neue Subshell, in der gedit ausgeführt wird. Die >/dev/null 2>&1Shell leitet die Ausgabe an einen anderen Ort weiter (unterdrückt die Ausgabe). Und &am Ende rückt der Prozess in den Hintergrund.

Terminal-Multiplexing

Auch Terminal-Multiplexing über Bildschirm oder Byobu . Sie führen das Programm grundsätzlich in einem eigenen Terminal aus. Ich kann byobu auch aus anderen Gründen wirklich empfehlen. Nachfolgend finden Sie eine Liste von Boybu-Verknüpfungen, die für Ihre ersten Schritte nützlich sein könnten:

Nützlich:

  • F2 Erstelle ein neues Fenster
  • F3 Zum nächsten Fenster wechseln
  • F4 Zum vorherigen Fenster wechseln
  • F6 Trennen Sie sich von der Sitzung und melden Sie sich ab
  • Shift-F6 Trennen Sie sich von der Sitzung, aber melden Sie sich nicht ab
  • F7 Rufen Sie den Scrollback- / Suchmodus auf
  • Ctrl-F5 Schließen Sie alle SSH / GPG-Sockets oder Agenten wieder an

Weniger nützlich:

  • Shift-F2 Teilen Sie den Bildschirm horizontal
  • Ctrl-F2 Teilen Sie den Bildschirm vertikal
  • Shift-F3 Bewegen Sie den Fokus zum nächsten Split
  • Shift-F4 Verschiebt den Fokus zum vorherigen Split
  • Shift-F5 Alle Teilungen reduzieren
  • F5 Aktualisieren Sie alle Statusbenachrichtigungen
  • F8 Benennen Sie das aktuelle Fenster um
  • F9 Starten Sie das Byobu-Konfigurationsmenü
  • F12 Escape-Taste von GNU Screen
  • Alt-Pageup Blättern Sie zurück durch den Verlauf dieses Fensters
  • Alt-Pagedown Blättern Sie vorwärts durch den Verlauf dieses Fensters
  • Ctrl-a-! Schaltet alle Tastenkombinationen von Byobu ein oder aus

Der At-Daemon und andere

atist ein nützliches kleines Tool, um einen Befehl zu einem festgelegten Zeitpunkt auszuführen. Es kann "missbraucht" werden, um einen Befehl von der Shell zu trennen:

echo './myprogram myoption1 myoption2' | at now

Auch Sie können in setsidund schauen start-stop-daemon, aber die anderen Methoden sollten ausreichen.

verwechseln
quelle
Tipp: Wenn es nur einen Job gibt, ist die Job-ID optional, z. B. können Sie stattdessen bg %1nur eingeben bg.
MasterMastic
25

Das mysteriöse kaufmännische Und-Zeichen "&" scheint zu bewirken, dass das Terminal den Prozess in den Hintergrund stellt ... (aber ich bin nicht sicher, was dort passiert).

Es tut und ist oft das, was Sie wollen. Wenn Sie & vergessen haben, können Sie das Programm mit Strg-Z anhalten und es dann mit dem Befehl bg in den Hintergrund stellen - und diese Shell weiterhin verwenden.

Die Prozesse "stdin", "stdout" und "stderr" sind weiterhin mit dem Terminal verbunden. Sie können diese von / nach / dev / null oder einer anderen Datei umleiten (z. B. ein Ausgabeprotokoll irgendwo speichern), wie gewünscht:

some-program </dev/null &>/dev/null &
# &>file is bash for 1>file 2>&1

Sie können den Prozess in Jobs sehen, ihn wieder in den Vordergrund bringen (Befehl fg) und ihm Signale senden (Befehl kill).

Einige Grafikprogramme lösen sich vom Terminal. In diesem Fall wird beim Ausführen des Befehls "normal" das grafische Programm gestartet und "beendet".


Hier ist ein kurzes Skript , das Sie in ~ / bin platzieren können , das ich runbg nannte:

#!/bin/bash
[ $# -eq 0 ] && {  # $# is number of args
  echo "$(basename $0): missing command" >&2
  exit 1
}
prog="$(which "$1")"  # see below
[ -z "$prog" ] && {
  echo "$(basename $0): unknown command: $1" >&2
  exit 1
}
shift  # remove $1, now $prog, from args
tty -s && exec </dev/null      # if stdin is a terminal, redirect from null
tty -s <&1 && exec >/dev/null  # if stdout is a terminal, redirect to null
tty -s <&2 && exec 2>&1        # stderr to stdout (which might not be null)
"$prog" "$@" &  # $@ is all args

Ich schaue das Programm ($ prog) nach, bevor ich es umleite, damit Fehler beim Auffinden gemeldet werden können. Führen Sie es als "runbg your-command args ..." aus. Sie können stdout / err weiterhin in eine Datei umleiten, wenn Sie die Ausgabe irgendwo speichern müssen.

Mit Ausnahme der Weiterleitungen und der Fehlerbehandlung entspricht dies der Antwort von htorque .

Gemeinschaft
quelle
Okay, danke ... Es scheint, dass ctrl-z(suspend) mir wieder Zugriff auf die Befehlszeile gibt, aber die GUI ausblendet, bis ich ein Problem erreiche, bgdas die Suspendierung zu lösen scheint. (macht Sinn) ... Gibt es einen anderen Befehl, mit dem ich die GUI trennen kann ... Aha! Ich verstehe jetzt, was du mit sighals (kill command)... meinst (interessante Dinge, diese Signale). Ich habe ein Code-Snippet verwendet, um es ddprogressiv auszugeben. Und es hat kill+ ein SIGNAL verwendet "?
Peter.O
Ich habe gerade Ihren Kommentar zu Ricks Antwort bemerkt ... Ich habe versucht, disown Jobs -p gedit`` zu entfernen, und es schien, als würde der Job entfernt werden ... (aber ich habe Systemmeldungen im Terminal erhalten, als ich gedit manuell geschlossen habe ... aber ich denke Ich habe im Moment ein vermasseltes Terminal ... zu viel experimentiert :(
Peter.O 31.10.10
@fred: Jobs werden von der Shell verwaltet, daher kann dies kein Signal steuern. Möglicherweise empfiehlt es sich, mehrere Shells zu starten. Auf mehreren GUI-Terminals sind Registerkarten zulässig, und Sie können screen oder tmux verwenden.
2
@fred: Besser nicht ausführen, jobs -p commandwenn mehrere Instanzen eines Befehls gleichzeitig im Hintergrund ausgeführt werden. Mit können jobsSie die richtige Job-ID finden und anschließend jobs -p <job-id>die PID des Jobs ermitteln. Persönlich finde ich die Version mit der Subshell viel einfacher. ;-)
htorque 31.10.10
2
@ htorque, fred: Sie können disown ohne Parameter ausführen, damit bash den letzten Job ablehnt:gedit & disown
22

Um eine Anwendung zu starten und vom gestarteten Terminal zu trennen, verwenden Sie & !.

firefox &!
Rick
quelle
6
Gut zu wissen, aber das scheint nur zsh zu sein. In Bash müssten Sie manuell ausgeführt werden, disown <pid-of-command>nachdem Sie den Befehl im Hintergrund gestartet haben .
htorque
Interessant ... Ich werde mich mit zsh befassen, aber als Linux-Neuling bleibe ich
vorerst
Was macht das Ausrufezeichen?
verrückt nach natty
1
Das ! unterbricht den Anwendungsprozess vom Terminalprozess, sodass Sie das Terminal schließen können, ohne dass die Anwendung, die gestartet wurde, geschlossen wird. Es scheint eine zsh Sache zu sein, aber praktisch.
Rick
Aber das hat auch bei bash @htorque geklappt ... Ich denke, das ist kein Problem.
Jasser
20

Verwenden nohup

nohup ist ein Programm, das einen bestimmten Befehl mit ignorierten Aufhängesignalen ausführt, sodass der Befehl im Hintergrund ausgeführt werden kann, nachdem der übergeordnete Prozess beendet wurde. Siehe die Manpage

Zum Beispiel:

nohup gedit something
Florian Diesch
quelle
2
Was ist nohup? Bitte erläutern Sie.
Oxwivi
3
nohup ist ein Programm, das einen bestimmten Befehl mit ignorierten Aufhängesignalen ausführt, sodass der Befehl im Hintergrund ausgeführt werden kann, nachdem der übergeordnete Prozess beendet wurde. Siehe die Manpage
Florian Diesch
Eigentlich denke ich, dass meine Antwort hier falsch ist. Auf weitere Überlegungen nohupsollte in diesem Szenario zurückgegriffen werden.
Boehj
2
Wenn eine interaktive Shell ein SIGHUP-Signal empfängt, kann sie (abhängig von den Einstellungen) ein SIGHUP-Signal an alle untergeordneten Benutzer senden. Dies kann passieren (oder auch nicht), wenn ein Terminal geschlossen ist. Ein Kind, das nicht bereit ist, ein solches Signal zu verarbeiten, führt die Standardaktion aus, dh das Beenden. Die nohupAnwendung (und die integrierte disownBash) lassen nicht zu, dass das Signal die Anwendung erreicht.
Enzotib
2
Eine Sache, auf die Sie achten müssen, ist die nohupErstellung einer Datei im aktuellen Verzeichnis namens nohup.out. Weitere Informationen finden Sie auf der Manpage . Ich bevorzuge disownaus diesem Grund und für die Tatsache, dass disownnach dem Start funktioniert gedit.
Flimm
4

Öffnen Sie das Terminal, geben Sie screen ein , geben Sie den Befehl ein, den Sie ausführen möchten, und schließen Sie das Terminal. Das Programm sollte weiterhin in der GNU Screen- Sitzung ausgeführt werden.

RobinJ
quelle
Was genau ist GNU Screen?
Oxwivi
Wenn ich die Idee richtig verstehe, ist es eine Art Fenstermanager für die Befehlszeile. Sie können damit mehrere Programme gleichzeitig in einer Befehlszeilenschnittstellensitzung ausführen.
RobinJ
Byobu?
Oxwivi
In etwa ist nur Byobu einfacher zu bedienen. Wenn ich mich nicht irre, ist Byobu nur eine einfachere Schnittstelle für GNU Screen.
RobinJ
1

Das hat bei mir funktioniert:

$ (nohup gedit 2>/dev/null &)
wesleycoder
quelle
1

xdg-open

Schauen Sie sich dieses universelle Dienstprogramm an: https://linux.die.net/man/1/xdg-open

Dadurch wird ein relativer Speicherort in Ihrem Dateimanager geöffnet.

 $ xdg-open .

Dadurch wird eine PDF-Datei in einem PDF-Reader geöffnet.

 $ xdg-open foo.pdf

Sie können sogar Web-URLs bereitstellen

$ xdg-open www.google.com
Jonathan Komar
quelle
0

Wie viele Leute dachten, ist Nohup die Sache, die man bedenken sollte. Aber nohup stills bleibt auf dem Terminal offen und zeigt die Programmaktivität auf dem Terminal an, was irritierend ist. Sie können das Terminal danach einfach schließen, um dies zu vermeiden. Ich habe eine sehr einfache Problemumgehung gefunden, die ich verwende.

nohup gedit & exit

Und das ist es. Es öffnet gedit und schließt das Terminal, wenn gedit gestartet wird. Da gedit jetzt nicht mit dem Terminal verbunden ist, bleibt es aktiv.

Lokesh Devnani
quelle
0

Dies funktioniert sogar innerhalb eines Skripts (Wie bei Aliases ist der & -Anhänger in Skripts normalerweise nicht zulässig, da sie nicht interaktiv sind):

bash -i >/dev/null 2>&1 <<<'nohup gedit &'
Sam
quelle
0

Das hat bei mir funktioniert:

$ (some-program &) &>/dev/null

# Examples:
$ (gedit &) &>/dev/null
$ (google-chrome &) &>/dev/null
Eyal Levin
quelle