• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst]Perl - STDIN-Zeile vorgeben/editieren

utopos

Member
Hallo zusammen,

in einem Perl-Skript lese ich an einer Stelle eine Anweisung des Benutzers von der Kommandozeile ein:

Code:
	print "\n\n Bitte neuen Befehl eingeben.\n";
	$eingabe = <STDIN>;	
	chomp ($eingabe);
	## mache schlaue Sachen mit $eingabe ##

So weit, so gut.-
Nun aber komme ich in die Lage, dass das Programm schon einen guten Tipp hat, was der Benutzer als nächstes möchte.
Diese Eingabe sollte also schon erscheinen, aber auch editierbar sein, d.h. wenn das Programm "Vorschlag" vorgibt, sollte der Benutzer
a) durch Eingabe von "1" die Anweisung "Vorschlag1" erzeugen können,
b) andererseits mithilfe von Backspaces auch "Vorgabe" daraus machen können.

Folgender Code funktioniert nicht:

Code:
	print "\n\n Bitte neuen Befehl eingeben.\n";
	print "Vorschlag";
	$eingabe = <STDIN>;	
	chomp ($eingabe);

Wenn es nur um das Hinzufügen von Zeichen ginge (nicht um Navigieren, Einfügen und Löschen) könnte man so vorgehen:

Code:
	print "\n\n Bitte neuen Befehl eingeben.\n";
	print "Vorschlag";
	$eingabe = <STDIN>;	
	chomp ($eingabe);
	$eingabe = 'Vorschlag' . $eingabe;

Gibt es da vielleicht ein Modul, das das Problem allgemein löst?

Vielen Dank

Utopos
 

abgdf

Guru
Ja, aber nicht ohne weiteres:
Code:
#!/usr/bin/perl

use warnings;
use strict;

use Term::ReadLine;

print "Bitte neuen Befehl eingeben.\n";
print "Bitte einmal Pfeil nach oben drücken, um einen Vorschlag zu erhalten.\n";
my $t = Term::ReadLine->new();
$t->addhistory("Vorschlag");
my $eingabe = $t->readline();
chomp($eingabe);

print "\n$eingabe\n";
http://docstore.mik.ua/orelly/perl/cookbook/ch15_12.htm

Das heißt ohne die History-Funktion (mit dem "Pfeil nach oben") zu verwenden, wird's auch mit "Term::ReadLine" nicht so leicht.
"Term::ReadLine::Gnu" kennt eine "insert_text"-Funktion, aber ich versteh' nicht, wie man die benutzt.
Guck' Dir auch mal Term::UI an:

http://search.cpan.org/~bingos/Term-UI-0.42/lib/Term/UI.pm

Meistens mach' ich das auch so mit einer Auswahl "1", "2", "3", wenn das geht, aber schreibe das dann selbst. Mir gefällt nicht so gut, wie sein UI aussieht. :)
 
OP
U

utopos

Member
Ja, perfekt!

Term::Readline mit der Chronik-Funktion ist eigentlich genau, was ich suchte - ich hatte nur vorsichtshalber erst einmal nach der allgemeinere Funktion gefragt.
Habe den Modul eingebunden und verwendet; und wenn es Arbeit für ihn gibt, tut er auch das richtige:

Code:
	my $term = Term::ReadLine->new();
	$term->addhistory(@chronik);
	$eingabe = $term->readline();

Angenehme Eigenschaft von addhistory: Es nimmt auch Listen als Argument an.

Leider aber erzeugt mein Programm jetzt einige für mich unverständliche Warnungen:

Use of uninitialized value in subroutine entry at /usr/lib/perl5/vendor_perl/5.16.2/i586-linux-thread-multi/Term/ReadLine/Gnu.pm line 647.
Use of uninitialized value in subroutine entry at /usr/lib/perl5/vendor_perl/5.16.2/i586-linux-thread-multi/Term/ReadLine/Gnu.pm line 719.
Use of uninitialized value $prompt in concatenation (.) or string at /usr/lib/perl5/vendor_perl/5.16.2/i586-linux-thread-multi/Term/ReadLine/Gnu.pm line 301.

Obwohl hier keine direkte Referenz zum meinem Skript gegeben wird, ist sicher, dass die Probleme im obigen Codestück entstehen.
Die Variablen @chronik und $eingabe sind in meinem Skript global und haben auch immer einen Wert (im Zweifelsfall () bzw. '').

Das ist nicht weiter schmerzhaft, denn die Funktion der Eingabezeile ist einwandfrei. Natürlich versuche ich trotzdem, solche Warnungen zu eliminieren.

Habe ich hier etwas offensichtliches falsch gemacht?
 
OP
U

utopos

Member
Ich habe es durch Ausprobieren herausgefunden:

Ich gebe den Funktionen einfach einen beliebigen String als Argument mit.

Code:
	my $term = Term::ReadLine->new('Terminal');
	$term->addhistory(@chronik);
	$eingabe = $term->readline('');

... läuft ohne Warnungen durch!

OK, Warnungen loswerden ist in Perl ja eigentlich einfacher, aber man will ja nicht auf alle anderen verzichten müssen ... :)

Vielen Dank für Eure Hilfe!
 
Oben