GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Kann Bash in seinen eigenen Eingabestrom schreiben?

Ist es in einer interaktiven Bash möglich Shell, um einen Befehl einzugeben, der einen Text ausgibt, der an der nächsten Eingabeaufforderung angezeigt wird, als ob der Benutzer diesen Text an dieser Eingabeaufforderung eingegeben hätte ?

Ich möchte source können ein Skript, das eine Befehlszeile generiert und ausgibt, so dass sie erscheint, wenn die Eingabeaufforderung nach dem Ende des Skripts zurückkehrt, sodass der Benutzer sie optional bearbeiten kann, bevor er enter drückt um es auszuführen.

Dies kann mit xdotool erreicht werden aber das funktioniert nur, wenn sich das Terminal in einem X-Fenster befindet und nur, wenn es installiert ist.

[[email protected]] 100 $ xdotool type "ls -l"
[[email protected]] 101 $ ls -l  <--- cursor appears here!

Kann das nur mit bash gemacht werden?

Akzeptierte Antwort:

Mit zsh , können Sie print -z verwenden um etwas Text in den Puffer des Zeileneditors für die nächste Eingabeaufforderung zu stellen:

print -z echo test

würde den Zeileneditor mit echo test vorbereiten die Sie an der nächsten Eingabeaufforderung bearbeiten können.

Ich denke nicht bash hat eine ähnliche Funktion, aber auf vielen Systemen können Sie den Eingangspuffer des Terminalgeräts mit dem TIOCSTI vorbereiten ioctl() :

perl -e 'require "sys/ioctl.ph"; ioctl(STDIN, &TIOCSTI, $_)
  for split "", join " ", @ARGV' echo test

Würde echo test einfügen in den Eingangspuffer des Terminalgeräts, als ob es vom Terminal empfangen worden wäre.

Eine tragbarere Variante der Terminology von @mike Ansatz, der die Sicherheit nicht beeinträchtigt, wäre, dem Terminalemulator einen ziemlich standardmäßigen query status report zu senden Escape-Sequenz:<ESC>[5n welche Terminals immer antworten (also als Eingabe) als <ESC>[0n und binden Sie das an die Zeichenfolge, die Sie einfügen möchten:

bind '"e[0n": "echo test"'; printf 'e[5n'

Wenn innerhalb von GNU screen , können Sie auch Folgendes tun:

screen -X stuff 'echo test'

Mit Ausnahme des IOCSTI-ioctl-Ansatzes bitten wir jetzt den Terminalemulator, uns eine Zeichenfolge zu senden, als ob sie getippt wäre. Wenn dieser String vor readline kommt (bash ’s line editor) hat das lokale Echo des Terminals deaktiviert, dann wird diese Zeichenfolge nicht angezeigt am Shell-Prompt, was die Anzeige leicht durcheinander bringt.

Um dies zu umgehen, könnten Sie entweder das Senden der Anfrage an das Terminal etwas verzögern, um sicherzustellen, dass die Antwort ankommt, wenn das Echo von readline deaktiviert wurde.

bind '"e[0n": "echo test"'; ((sleep 0.05;  printf 'e[5n') &)

(hier unter der Annahme, dass Sie sleep unterstützt eine Auflösung von weniger als einer Sekunde).

Verwandte:Slash und Backslash in sed?

Idealerweise möchten Sie so etwas tun:

bind '"e[0n": "echo test"'
stty -echo
printf 'e[5n'
wait-until-the-response-arrives
stty echo

Allerdings bash (im Gegensatz zu zsh ) hat keine Unterstützung für ein solches wait-until-the-response-arrives das die Antwort nicht liest.

Es hat jedoch einen has-the-response-arrived-yet Funktion mit read -t0 :

bind '"e[0n": "echo test"'
saved_settings=$(stty -g)
stty -echo -icanon min 1 time 0
printf 'e[5n'
until read -t0; do
  sleep 0.02
done
stty "$saved_settings"

Weiterführende Literatur

Sehen Sie sich die Antwort von @starfry an, die die beiden Lösungen von @mikeserv und mir um einige detailliertere Informationen erweitert.


Linux
  1. Bash:Echo:Schreibfehler:Ungültiges Argument?

  2. Verwenden von Case-Anweisungen in Bash

  3. Passworteingabe am Terminal ausblenden

  4. Bash-Shell-Skript - Suchen Sie nach einem Flag und holen Sie sich seinen Wert

  5. Wie kann ich die Anzahl der Zeichen in einer Bash-Variablen zählen?

Wie schreibe ich eine Schleife in Bash?

So schreiben Sie ein Bash-Skript mit Beispielen

Bash:In Datei schreiben

Bash/sh 'if else'-Anweisung

kann ein programm seinen eigenen elfabschnitt lesen?

Was ist die Verwendung von $ # in Bash