Ich würde gerne so etwas machen:
bash -c "some_program with its arguments"
Aber um eine interaktive Bash zu haben, läuft sie nach dem some_program
Ende weiter.
Ich bin mir sicher, dass -c
das kein guter Weg ist man bash
:
Eine interaktive Shell wird ohne optionale Argumente und ohne die Option -c gestartet
Wie mache ich das?
Das Hauptziel wird hier beschrieben
HINWEIS
- Ich muss
some_program
von Zeit zu Zeit kündigen - Ich möchte es nicht in den Hintergrund stellen
- Ich möchte auf dem Laufenden bleiben
bash
, um etwas anderes zu tun - Ich möchte das Programm erneut ausführen können
pty.
fg
Antworten:
Dies geschieht jedoch besser über ein Skript mit.
exec $0.
Oder wenn einer dieser Dateideskriptoren auf ein Endgerät verweist, das derzeit nicht verwendet wird, hilft dies - Sie müssen sich daran erinnern, dass auch andere Prozesse dieses Terminal überprüfen möchten.Übrigens, wenn Ihr Ziel, wie ich annehme, darin besteht, die Umgebung des Skripts nach dessen Ausführung zu erhalten, werden Sie wahrscheinlich viel besser bedient:
Die Shells
.dot
undbash's source
sind nicht ein und dasselbe - die.dot
Shells sind POSIX-spezifisch als spezielle eingebaute Shell spezifiziert und daher so nah wie möglich an der Garantie, obwohl dies keineswegs eine Garantie dafür ist, dass sie da sind ...Obgleich das oben genannte mit wenig Ausgabe tun sollte, wie Sie erwarten. Zum Beispiel können Sie:
Die Shell führt Ihr Skript aus und kehrt zur interaktiven Eingabeaufforderung zurück - sofern Sie nicht
exit
die Shell aus Ihrem Skript entfernen oder Ihren Prozess im Hintergrund ausführen -, mit der Ihre E / A verknüpft wird/dev/null.
DEMO:
VIELE
JOBS
Ich bin der Meinung, dass Sie sich ein wenig mit den integrierten Aufgabenverwaltungsoptionen der Shell vertraut machen sollten. @Kiwy und @jillagre haben dies bereits in ihren Antworten angesprochen, aber es könnte weitere Einzelheiten rechtfertigen. Und ich habe schon ein POSIX-spezifizierte spezielle Shell erwähnt eingebaut, aber
set, jobs, fg,
undbg
sind ein paar mehr, und als eine andere Antwort zeigt ,trap
undkill
zwei weitere noch.Wenn Sie noch keine Sofortbenachrichtigungen zum Status gleichzeitig ausgeführter Hintergrundprozesse erhalten, liegt dies daran, dass Ihre aktuellen Shell-Optionen auf den von POSIX angegebenen Standardwert von festgelegt
-m
sind. Sie können diese jedoch auch asynchronset -b
abrufen:Ein sehr grundlegendes Merkmal von Unix-basierten Systemen ist die Art und Weise, wie sie verarbeitet werden
signals
. Ich habe einmal einen aufschlussreichen Artikel zu diesem Thema gelesen , der diesen Prozess mit Douglas Adams 'Beschreibung des Planeten NowWhat in Einklang bringt:Dies bezieht sich auf
kill signals
.Zumindest für mich beantwortete das obige Zitat viele Fragen. Zum Beispiel hatte ich es immer als sehr seltsam und überhaupt nicht intuitiv empfunden, dass ich einen
dd
Prozess überwachen musste , wenn ich ihn überwachen wolltekill
. Nachdem ich das gelesen hatte, ergab es Sinn.Ich würde sagen, die meisten von ihnen versuchen nicht aus gutem Grund , sich anzupassen - es kann weitaus ärgerlicher sein als es ein Segen, wenn eine Reihe von Prozessen Ihr Terminal mit den Informationen spammt, die die Entwickler für Sie als wichtig erachtet haben .
Je nach Terminalkonfiguration (die Sie mit überprüfen
stty -a
) ,CTRL+Z
ist wahrscheinlich Satz ein weiterleitenSIGTSTP
den aktuellen Vordergrundprozess Gruppenleiter, die Wahrscheinlichkeit , dass Ihr Schal ist und das sollte auch standardmäßig so konfiguriert werden ,trap
dass Signal und unterbrechen Sie Ihren letzten Befehl. Wie die Antworten von @jillagre und @Kiwy zusammen zeigen, können Sie diese Funktionalität ohne weiteres an Ihren gewünschten Zweck anpassen.SCREEN JOBS
Um diese Funktionen nutzen zu können, müssen Sie sie zunächst verstehen und ihre Handhabung an Ihre eigenen Bedürfnisse anpassen. Ich habe zum Beispiel gerade diesen Screenrc auf Github gefunden , der
screen
Tastaturbelegungen für Folgendes enthältSIGTSTP
:Das macht es einfach, einen Prozess, der als untergeordneter
screen
Prozess ausgeführt wird, oder denscreen
untergeordneten Prozess selbst anzuhalten, wie Sie es wünschen.Und gleich danach:
ODER:
Wäre Vordergrund oder Hintergrund des Prozesses, wie Sie es vorgezogen haben. Die
jobs
eingebaute kann Ihnen jederzeit eine Liste dieser zur Verfügung stellen. Das Hinzufügen des-l
Operanden enthält PID-Details.quelle
Hier ist eine kürzere Lösung, die das erreicht, was Sie wollen, aber möglicherweise keinen Sinn ergibt, wenn Sie das Problem nicht verstehen und wissen, wie bash funktioniert:
Dadurch wird eine Bash-Shell gestartet
some_program
und nach demsome_program
Beenden wird eine Bash-Shell aufgerufen.Grundsätzlich füttern wir einen String mit STDIN. Diese Zeichenfolge ist
some_program with its arguments; exec </dev/tty
. Dies weist bash an,some_program
zuerst zu starten und danach auszuführenexec </dev/tty
. Anstatt also weiterhin Befehle aus der übergebenen Zeichenfolge zu lesen, beginnt die Bash mit dem Lesen ab/dev/tty
.Das
-i
liegt daran , dass , wenn bash startet, überprüft er, ob STDIN ein tty ist, und wenn es beginnt , ist es nicht. Aber später wird es so sein, also zwingen wir es in den interaktiven Modus.Eine andere Lösung
Eine andere Idee, von der ich dachte, dass sie sehr portabel wäre, wäre, das Folgende ganz am Ende Ihrer
~/.bashrc
Datei einzufügen.Wenn Sie dann zuerst eine Shell mit einem Befehl starten möchten, tun Sie einfach Folgendes:
Erläuterung:
Das meiste davon sollte offensichtlich sein, aber der Grund für das Ändern des Variablennamens ist, dass wir die Variable lokalisieren können. Da
$START_COMMAND
es sich um eine exportierte Variable handelt, wird sie von allen untergeordneten Elementen der Shell geerbt. Wenn eine andere Bash-Shell eines dieser untergeordneten Elemente ist, wird der Befehl erneut ausgeführt. Also weisen wir den Wert einer neuen nicht exportierten Variablen zu ($start_command
) und löschen die alte.quelle
<<<
ist nicht POSIX, aber Sie könntenecho "string here" | bash -i
stattdessen. Dann gibt es/dev/tty
was, was eine Linux-Sache ist. Aber Sie könnten die FD täuschen, bevor Sie bash starten, und dann STDIN erneut öffnen, was ähnlich aussieht wie das, was Sie tun, aber ich habe mich dafür entschieden, die Dinge einfach zu halten./dev/tty
ist keine Linux-Sache, aber definitiv POSIX.Dies sollte den Trick machen:
Bearbeiten:
Hier ist ein neuer Versuch nach Ihrem Update:
Verwenden ControlCSie, Sie werden dieses kleine Menü präsentiert:
Das ist der Fall.
Wählen Sie die Option "Bash"
Wählen Sie die Option "Neustart"
quelle
CTRL+C
ist nur ein Nebeneffekt der Standardkonfiguration Ihres Terminals, um es als zu interpretierenSIGINT
. Sie können dies wie gewünscht ändernstty
.SIGINT
isttrapped
oben mit2
.Sie können dies tun, indem Sie Ihr Skript als Initialisierungsdatei übergeben:
Oder Sie geben es in der Kommandozeile weiter:
Beachten Sie, dass
--init-file
dies zum Lesen systemweiter Initialisierungsdateien gedacht war,/etc/bash.bashrc
sodass Sie diese möglicherweisesource
in Ihrem Skript verwenden möchten .quelle
Ich verstehe den Sinn nicht wirklich, da Sie nach dem Ausführen dieses Programms bereits zu einer Shell zurückkehren. Sie könnten jedoch dazu:
Dadurch wird eine interaktive Bash gestartet, nachdem das Programm ausgeführt wurde.
quelle
Sie könnten den Befehl in den Hintergrund stellen, um Ihre aktuelle Bash offen zu halten:
Um zur Ausführung zurückzukehren, können Sie den
fg
Befehl verwenden und^+z
ihn wieder in den Hintergrund stellenquelle
bash
oder nicht, du verwendest für mich eine sehr fremde Shell, wenn sie nicht mit Prozesshintergründen umgehen kann. Und ich stimme Kiwi zu - diese Informationen würden Ihnen besser dienen, wenn es in Ihrer Frage wäre.Möglicherweise möchten Sie den Bildschirm verwenden, um den Befehl auszuführen. Sie können dann nach Abschluss des Befehls erneut eine Verbindung zur Sitzung herstellen.
Alternativ können Sie den Befehl auch im Hintergrund ausführen
some_program with its arguments&
. Dadurch haben Sie die Möglichkeit, den Befehl erneut auszuführen und den Status des Befehls abzurufen, sobald er ausgeführt wurde.quelle
screen
aber es in den Hintergrund zu stellen ist für mich nicht nützlich - ich muss manchmal das Programm beenden, etwas anderes tun und es erneut ausführen. Und das Hauptziel ist es, dies schnell zu tun.kill %
oder beendenkill %1
.