Wie kann ich vi verwenden, um die Eingabeaufforderungszeile eines Dienstprogramms zu bearbeiten? [geschlossen]

8

Ich habe ein Dienstprogramm in bash geschrieben, mit read -edem eine Eingabeaufforderung für SQL-ähnliche Abfragen bereitgestellt wird. Manchmal sind diese lang, daher möchte ich vi öffnen, die aktuelle Zeile bearbeiten und beim Beenden die Zeile durch den Inhalt in vim ersetzen können. Ich lese Zeilen mit read. Etwas wie:

query> select .... from .... very long... <ctrl-e> 

jetzt in vi

select .... from .... very long...

bearbeiten zu

select ...
from ....
very long ...

Ausfahrt vi

query> select ...
from ....
very long ... <enter>

Abfrage wird ausgeführt.

UPDATE: Die Verwendung von 'set -o vi' vor dem 'read -e' scheint für mich <esc>vder richtige Weg zu sein, aber derzeit enthält das Öffnen des Puffers nicht das, was sich in der Zeile befindet, sondern eine andere Abfrage aus meinem Verlauf (aber nicht die, die ich vorher getippt habe).

IttayD
quelle
1
Wenn Sie Oracle SqlPlus verwenden, müssen Sie DEFINE _EDITOR = vimIhrer Frage hinzufügen, welches Datenbanksystem Sie verwenden.
Hschou
2
Ist dies aus einem Shell-Skript, wie aus Ihren Tags hervorgeht? Und mit Bashs integriertem readBefehl?
Toby Speight
2
"Ein Dienstprogramm, das SQL-ähnliche Abfragen akzeptiert" - Welches Dienstprogramm? Mehrdeutigkeit ist schlecht. Wie Sie sehen können, handelt es sich bei beiden aktuellen Antworten um Bash, nicht um Ihr "Dienstprogramm".
Patrick
Vielleicht möchten Sie sich das dbext-Plugin ansehen .
Satō Katsura

Antworten:

14

Zuerst müssen Sie sicherstellen, dass vi als Shell-Befehlszeileneditor verwendet wird:

set -o vi

Jetzt können Sie Ihren Befehl in die Befehlszeile eingeben / kopieren. Verwenden Sie Escoder Shift+, um den Einfügemodus zu verlassen und in den normalen Modus zu wechseln Tab. Jetzt können Sie vidurch Drücken öffnen v.

In vikönnen Sie jetzt alle gewünschten Änderungen vornehmen, den Puffer speichern und beenden vi, und der Befehl wird ausgeführt.

pfnuesel
quelle
2
Das funktioniert in vielen Shells, aber funktioniert es in einem Programm, das GNU Readline verwendet? Ich habe mit psqlund auch mit anderen interaktiven Programmen getestet . Es funktioniert nicht, auch wenn ich es einpacke rlwrap.
Kusalananda
1
Mir ist nicht klar, ob das OP dies in der Shell oder auf Aufforderung eines externen Dienstprogramms tut.
Kusalananda
Ich mache das in einem Dienstprogramm, das ich geschrieben habe
IttayD
habe das versucht. Wenn ich 'v'
eingebe,
9

In Bash können Sie mit Ctrl+ x, Ctrl+ einen Editor für die aktuelle Befehlszeile aufrufen e.

Auf dem System, das ich zur Hand haben muss, befindet sich dies nicht in den Dokumenten unter man readlinesich, sondern im man bashAbschnitt "Readline". Daher bin ich mir nicht sicher, ob es sich um eine Bash-spezifische Funktion handelt oder ob andere Readline-basierte Programme dies tun würden unterstütze es.

Hier ist die Dokumentation von bash:

edit-and-execute-command( C-xC-e)

Rufen Sie einen Editor in der aktuellen Befehlszeile auf und führen Sie das Ergebnis als Shell-Befehle aus. Bash versucht aufzurufen $VISUAL, $EDITORund emacsals Herausgeber, in dieser Reihenfolge.

IMSoP
quelle
1
Nur eine Anmerkung - damit das readeingebaute Gerät die interaktiven readlineEinstellungen (einschließlich der edit-and-execute-commandBindung) verwendet, müssen Sie es als aufrufen read -e. Übrigens habe ich bestätigt, dass dies funktioniert.
Toby Speight
5

Solange Ihre Eingabeaufforderung eine Shell-Eingabeaufforderung ist (z. B. ein Aufruf an read), sind alle anderen Antworten gültig und nützlich

Wenn dies nicht der Fall ist (diesbezüglich ist Ihnen nicht ganz klar), z. B. wenn Sie einen SQL-Interpreter verwenden xxxsql, können Sie rlwrap --multi-line -a xxxsqleinen speziellen (konfigurierbaren) Schlüssel verwenden und dann den Editor Ihrer Wahl aufrufen (angegeben durch z. B. export RLWRAP_EDITOR="vim '+call cursor(%L,%C)"in der Eingabe - Das call_cursorist nützlich, um die Cursorposition beim Aufrufen beizubehalten. vim)

Als zusätzlichen Vorteil haben Sie auch für die mehrzeiligen Befehle (die in einzeilige Befehle "komprimiert" werden, bevor sie in die Verlaufsliste aufgenommen werden, aber bei erneuter Verwendung erneut erweitert werden) den vollständigen Befehlsverlauf.

Bearbeiten: Weitere Informationen finden Sie auf der rlwraps Github-Seite . Wie alle Befehle, die die Verwendung des GNU Readline - Bibliothek der meisten seines Verhaltens wird angegeben in den Benutzern $INPUTRC , die rlwraphat eine Reihe seiner eigenen Optionen hinzugefügt , dass die Kontrolle, die unter anderem der oben genannte Sondertaste einen externen Editor (aufzurufen CTRL+ ^standardmäßig )

Hans Lub
quelle
Dies scheint ein guter Ansatz zu sein, aber die Anweisungen scheinen unvollständig zu sein: Was ist standardmäßig der "Sonderschlüssel" und wo konfigurieren Sie ihn? Und ist rlwrapTeil eines separaten Pakets, das ich installieren muss? Es ist nicht auf den paar Linux-Boxen vorhanden, die ich vor mir habe.
IMSoP
Ich habe meine Antwort etwas erweitert, um sie vollständiger zu machen. rlwrapist nicht Linux-spezifisch, kann aber in den meisten Distributionen gefunden werden (normalerweise nicht standardmäßig installiert).
Hans Lub
Ich stimme IMSop zu, dies scheint der beste Ansatz zu sein. Es fehlt jedoch die Tatsache, rlwrapdass es vollständig im vi-Modus verwendet werden kann. Wenn Sie fügen set editing-mode viinnen ~/.inputrcdann rlwrapwird das respektieren und Ihre rlwrap xxxsql(zB rlwrap sqlite3) wird vi - Modus verwenden. RLWRAP_EDITORHacks sind nicht erforderlich .
gro♀
Dienstprogramme wie psqlpostgres und mysql bieten mysqlnative Unterstützung für readline, was viel besser funktioniert als der Versuch, sie zu verwenden rlwrap. sqlplusleider nicht.
Patrick
@gro♀: Die Frage betraf die mehrzeilige Bearbeitung. Sogar Readline-fähige Befehle können dafür erforderlich sein rlwrap(und set editing-mode vibestimmen dann nicht den Editor, der für mehrzeilige Bearbeitungen verwendet wird)
Hans Lub