Verfügt bash über einen Haken, um zu bestimmen, wann die Child-Shell beendet wird?

1094
vol7ron

In bashSpin t/cshdrehe ich eine Shell hoch, die tty input ( stty erase ^H) in der .cshrc aktualisiert, aber wenn exit-ing und zurück zum Bash geht, backspacefunktioniert der Schlüssel nicht mehr. Dies liegt daran, dass bash verwendet readlineund ich das Löschen ( stty erase ^?) zurücksetzen muss .

Wenn ich es traprichtig verstanden habe, scheint es, als könnte ich den t / csh-Exit innerhalb des t / csh-Prozesses abfangen und Befehle ausführen, nachdem er beendet wurde. Ich würde es jedoch vorziehen, wenn die Überfüllung in bash erfolgt, die idealerweise erkennen würde, dass eine Shell aufgerufen / beendet wurde, und dann ein Skript ausführt, um ihre Konfigurationen zurückzusetzen.

Dies wird bevorzugt, weil ich eine beliebige Anzahl von Granaten nennen könnte (zB dash, zsh), die versehentlich bash-spezifische Einstellungen ändern können. Anstatt mehrere trapBefehle für jede Shell beizubehalten, scheint es am besten, einen für bash zu haben.


Ist mein Verständnis von traprichtig? Wenn ja, kann bashein untergeordnetes Shell-Exit erkannt und dann ein Skript ausgeführt werden?

7

1 Antwort auf die Frage

7
Floofy Fox

Sie waren auf dem richtigen Weg mit trap. Was Sie wollen, ist folgendes:

trap "stty erase ^?" SIGCHLD 

Sie können das hinzufügen .bashrc. Beachten Sie, dass dies ausgeführt wird, wenn ein Teilprozess endet.

Dies funktioniert nur in interaktiven Sitzungen. Für nicht interaktive Sitzungen bash wird die Jobsteuerung standardmäßig nicht aktiviert. Sie müssen daher set -o monitorzuerst ausgeführt werden. Ich bezweifle jedoch, dass Sie in nicht-interaktiven Skripts Backspaces benötigen.

SIGCHLD wird an den übergeordneten Prozess gesendet, wenn ein Unterprozess beendet wird.


Eine alternative Methode besteht darin, die andere Shell in ein Skript einzubinden, z.

#!/bin/sh tcsh stty erase ^? 

Wenn Sie dann Ihre Shell über das Skript starten, führt das Skript den stty eraseBefehl aus, nachdem die Shell beendet wurde. Dies hat weniger Nebenwirkungen als ein globaler trapHandler, aber es funktioniert natürlich nur, wenn Sie das Skript jedes Mal starten (oder einen Aliasnamen dafür erstellen, z alias 'tcsh' '~/launch-tcsh.sh'. B. ).

Ich nehme an, bei den tty-Einstellungen ist der Job / die Kontrolle nicht so groß, aber alles andere ist wahrscheinlich ein sehr wichtiger Punkt. Meine Vermutung ist, dass es einen Weg gibt, den Kindprozess zu erkennen, und diese Falle nur dann ausführen, wenn es sich um eine andere Hülle handelt, aber genau darauf habe ich gehofft - ich war skeptisch, aber ich bin froh, dass ich gefragt habe - danke! vol7ron vor 7 Jahren 0
@ vol7ron Leider gibt es keine narrensichere Methode, um herauszufinden, was der untergeordnete Prozess von bash war. Sie können `jobs -n` verwenden, um kürzlich verlassene Jobs zu erhalten, und hoffentlich ist der letzte korrekt, aber es gibt dort eine Racebedingung. Ich denke, Sie könnten stattdessen die Skript-Wrapper-Alternative verwenden. Floofy Fox vor 7 Jahren 0
Ich hätte gedacht, dass der einfachste Weg, `^?` Einzugeben, darin besteht, das Zeichen `^ 'einzugeben, dann das Zeichen`? `:` Stty` erkennt, dass das Zeichen `^` ein Präfix für ein Steuerzeichen ist. Sie können Vim auch mit der "Control-V" -Taste "Backspace" mitteilen, dass Sie einen literalen Backspace-Charakter einfügen möchten. Adrian Pronk vor 7 Jahren 1
@AdrianPronk Danke, ich wusste nicht, dass "stty" das getan hat. Hatte das Vim-Wort an einer Stelle gearbeitet und dann etwas gestopft. Jedenfalls bearbeitet. Floofy Fox vor 7 Jahren 0