Ich bin auf eine Reihe von Erklärungen gestoßen, wie man redraw-current-line
mit einem Tastendruck zuordnet bind
, aber ich möchte die Eingabeaufforderung aus anderen Gründen (z. B. Timer, Hintergrundjob) neu zeichnen, ohne dass der Benutzer einen Tastendruck eingibt. Ich dachte, das wäre einfach, aber ich kann nichts finden. Danke!
Antwort1
Ich hatte das gleiche Problem, aber ich habe nichts zufriedenstellendes gefunden, daher hier einige Workarounds.
${PS1@P}
In neueren Bash-Versionen können Sie die Eingabeaufforderung einfach selbst ausdrucken echo "${PS1@P}"
. Die ${var@P}
Form der Variablenerweiterungen bedeutet, Eingabeaufforderungs-Escapes innerhalb einer Variablen zu erweitern.
kill -WINCH "$$"
Ein weiterer Trick, den Sie ausprobieren können, besteht darin, Ihre Shell mit zu beenden SIGWINCH
. Dadurch wird readline veranlasst, die Eingabeaufforderung neu zu zeichnen. Beispiel:
$ (sleep 2; echo foo; sleep 2; kill -WINCH "$$") &
[1] 2295
<immediately press l and s; the "foo" text will mess up the current line>
$ lsfoo
<after 1s the prompt is redrawn again without the parasitic text>
$ ls
ioctl(TIOCSTI)
Ein weiterer Trick besteht darin, einen unbenutzten Schlüssel wie redraw-current-line
üblich zu binden und diesen Schlüssel dann mit dem TIOCSTI
ioctl zu simulieren (dies funktioniert immer noch ohne zusätzliche Berechtigungen auf demaktuelltty in Linux). Dafür benötigen Sie jedoch entweder C, Perl, Python usw.:
$ bind '"\xff": redraw-current-line'
$ redraw_current_line(){ perl -e 'ioctl STDIN, 0x5412, $x = "\xff"' </dev/tty; }
$ (sleep 2; echo foo; sleep 2; redraw_current_line) &
.... same as in SIGWINCH example ...
Dieser letzte Trick ist nur für Linux verfügbar. TIOCSTI
Auf anderen Systemen, die ihn möglicherweise unterstützen, ist die Ioctl-Nummer anders.
Notiz:falls jemand meint, dass ich das tun sollte, require "sys/ioctl.h"
anstatt die Ioctl-Nummer fest zu verdrahten:Nein, das sollte ich nicht. Selbst wenn es zufällig funktioniert inDasFall, Perl h2ph
ist kaputt, und die .ph
Dateien solltennichtverwendet werden:
$ perl -e 'require "sys/ioctl.ph"; printf "%x\n", TIOCGPTN()'
80005430
$ cc -include stdio.h -include sys/ioctl.h -xc - \
<<<'int main(){printf("%lx\n",TIOCGPTN);}' -o /tmp/foo && /tmp/foo
80045430
Beachten Sie das zusätzliche Bit im Original: 80045430
!=80005430