Alleine die Frage ordentlich zu formulieren ist schon sehr schwierig...
j-alice ist ein Chat Programm auf Textbasis.
Ich möchte das starten, und von einem anderen Prozess aus
darauf zugreifen.
In meinem Falle ein Pearl Script, was als Bot im Opendchub läuft.
Momentan habe ich das mittels Screen und dessen copy und paste
Funktion gelöst. Das läuft aber mehr schlecht als recht.
Wie kann ich also dem laufendem j-alice prozess einfach die eingegebenen
text zukommen lassen, und alle ausgaben die auf dieser console gemacht
werden abfragen, oder in eine Datei speichern ?
Für jeden Hinweis, auch der wie ich die Frage besser formulieren könnte, wäre ich Dankbar
gruß thomas
j-alice (chat bot) anbinden an opendchub
So, da bin ich wieder. Habe heute mal schnell Perl gelernt
und bin soweit gekommen:
#!/usr/bin/perl -w
#Pipe zu anna oeffnet, wobei ein lesender/schreibender Zugriff gewnscht wird
#unlink ("/home/thomas/olaf/anna/output.txt");
$|=1; #STDOUT Pufferung abschalten
open(PIPEOUT, "| ./j-alice > output.txt");
print ("j-alice gestartet...");
# Alte Frage loeschen
unlink ("/home/thomas/olaf/anna/input.txt");
sleep(5);
unlink ("/home/thomas/olaf/anna/output.txt");
$i = 1;
while($i < 5)
{
if (-e "/home/thomas/olaf/anna/input.txt")
{
# Gestellte Frage auslesen und anna stellen
open (INFILE, "</home/thomas/olaf/anna/input.txt");
flock (INFILE, 2);
$meinefrage = <INFILE>;
close DATEI;
# Alte Frage loeschen
unlink ("/home/thomas/olaf/anna/input.txt");
# Alte Antwort loeschen
unlink ("/home/thomas/olaf/anna/output.txt");
print PIPEOUT "$meinefrage\n";
print ".\n";
sleep(1);
$i++;
}
else
{
# print(".");
sleep(1);
}
}
print ("j-alice beenden...");
system `killall j-alice`;
Das Programm liest die eingaben ueber input.txt ein, gibt sie an j-alice weiter, und schreibt ausgaben in die output.txt.
Das Problem ist jetzt nur, das die Output.txt Datei erst mit den Antworten des Programmes j-alice gefüllt wird, wenn das Programm beendet wird. Eben nicht
sofort. Das brauche ich aber unbedingt. Ihr wollt eine Antwort auf eine Frage
auch sofort, und nicht wen ihr beendet werdet
und bin soweit gekommen:
#!/usr/bin/perl -w
#Pipe zu anna oeffnet, wobei ein lesender/schreibender Zugriff gewnscht wird
#unlink ("/home/thomas/olaf/anna/output.txt");
$|=1; #STDOUT Pufferung abschalten
open(PIPEOUT, "| ./j-alice > output.txt");
print ("j-alice gestartet...");
# Alte Frage loeschen
unlink ("/home/thomas/olaf/anna/input.txt");
sleep(5);
unlink ("/home/thomas/olaf/anna/output.txt");
$i = 1;
while($i < 5)
{
if (-e "/home/thomas/olaf/anna/input.txt")
{
# Gestellte Frage auslesen und anna stellen
open (INFILE, "</home/thomas/olaf/anna/input.txt");
flock (INFILE, 2);
$meinefrage = <INFILE>;
close DATEI;
# Alte Frage loeschen
unlink ("/home/thomas/olaf/anna/input.txt");
# Alte Antwort loeschen
unlink ("/home/thomas/olaf/anna/output.txt");
print PIPEOUT "$meinefrage\n";
print ".\n";
sleep(1);
$i++;
}
else
{
# print(".");
sleep(1);
}
}
print ("j-alice beenden...");
system `killall j-alice`;
Das Programm liest die eingaben ueber input.txt ein, gibt sie an j-alice weiter, und schreibt ausgaben in die output.txt.
Das Problem ist jetzt nur, das die Output.txt Datei erst mit den Antworten des Programmes j-alice gefüllt wird, wenn das Programm beendet wird. Eben nicht
sofort. Das brauche ich aber unbedingt. Ihr wollt eine Antwort auf eine Frage
auch sofort, und nicht wen ihr beendet werdet
Die Antwort ist:
local $| = 1; # unbuffered mode
select (PIPEOUT); #STDOUT Pufferung abschalten
$| = 1
So bekomme ich die Pipe dazu sofort alle sachen rauszuschicken, nicht erst bei Programmende.
Hier nochmal das ganze Script, für alle ides Interessiert:
#!/usr/bin/perl -w
# Background script
# in verbindung mit opendchub. Wartet auf eine Frage mittels
# der Datei input.txt. und gibt die antwort von der KI Anna nach
# output.txt aus. in opendchub luft das zweite script namens
# anna.pl
# input.txt - aktuelle frage
# last_input.txt - alle fragen dieser session als log, um bei abstuerzen
# - den fehler finden zu koenne
# output.txt - antworten von anna
# anna.pl - zweiter script im dchub
local $| = 1; # unbuffered mode
select (PIPEOUT); #STDOUT Pufferung abschalten
$| = 1; # nicht erst bei programmende alles an Anna schicken !
#Pipe zu anna oeffnet, wobei ein lesender/schreibender Zugriff gewnscht wird
#unlink ("/home/thomas/olaf/anna/output.txt");
# Alte anworten loeschen
unlink ("/home/thomas/olaf/anna/output.txt");
# j-alice als nice level starten, und ausgaben an output.txt leiten
# dazu ein eingabe Pipe ffnen, um fragen an anne stellen zu koennen
open(PIPEOUT, "| nice ./j-alice > output.txt");
print ("j-alice gestartet...");
sleep(20); # erstmal anna in ruhe starten lassen
# Alte Frage loeschen
unlink ("/home/thomas/olaf/anna/input.txt");
unlink ("/home/thomas/olaf/anna/last_input.txt");
$i = 1;
while($i < 5)
{
if (-e "/home/thomas/olaf/anna/input.txt")
{
# Gestellte Frage auslesen und anna stellen
open (INFILE, "</home/thomas/olaf/anna/input.txt");
flock (INFILE, 2);
$meinefrage = <INFILE>;
close INFILE;
print PIPEOUT "$meinefrage\n";
# Alte Frage loeschen
unlink ("/home/thomas/olaf/anna/input.txt");
}
else
{
sleep(1);
}
}
print ("j-alice beenden...");
system `killall j-alice`;
Und das script zum einbinden in Opendchub:
# General Chat with the KI Anna, uses two scripts,
# this one and abfrage.pl, thats runs in background
# in verbindung mit opendchub. Wartet auf eine Frage und schreibt
# sie in die Datei input.txt. und gibt die antwort von der KI Anna nach
# opendchub aus.
# input.txt - aktuelle frage
# last_input.txt - alle fragen dieser session als log, um bei abstuerzen
# - den fehler finden zu koenne
# output.txt - antworten von anna
# abfrage.pl - zweiter script fuer anna
$botname = "Anna";
sub main ()
{
odch::register_script_name($botname);
}
sub data_arrival()
{
my($user,$data)=@_;
if($data =~ /[Aa]nna/)
{
$data =~ tr/!/./; # anna vertraegt keine !
$Zahl = index($data,">");
$data = substr($data, $Zahl+2);
$data = substr($data,0,length($data)-1);
if($data =~ /GetINFO/)
{
}
else
{
open(file, ">/home/thomas/olaf/anna/input.txt");
open(logfile, ">>/home/thomas/olaf/anna/last_input.txt");
print file $data;
print logfile $data;
close (file);
close (logfile);
sleep (2);
if (-e "/home/thomas/olaf/anna/input.txt")
{
odch::data_to_all("<Anna> I'am away.|");
# anna reagiert nicht, also nicht antworten
}
else
{
$output_string = `tail -n2 /home/thomas/olaf/anna/output.txt | grep Anna | cut -d \\> -f 3`;
# CR entfernen am ende
$output_string = substr($output_string,0,length($output_string)-1);
odch::data_to_all("<Anna> $output_string|");
return;
}
}
}
}
local $| = 1; # unbuffered mode
select (PIPEOUT); #STDOUT Pufferung abschalten
$| = 1
So bekomme ich die Pipe dazu sofort alle sachen rauszuschicken, nicht erst bei Programmende.
Hier nochmal das ganze Script, für alle ides Interessiert:
#!/usr/bin/perl -w
# Background script
# in verbindung mit opendchub. Wartet auf eine Frage mittels
# der Datei input.txt. und gibt die antwort von der KI Anna nach
# output.txt aus. in opendchub luft das zweite script namens
# anna.pl
# input.txt - aktuelle frage
# last_input.txt - alle fragen dieser session als log, um bei abstuerzen
# - den fehler finden zu koenne
# output.txt - antworten von anna
# anna.pl - zweiter script im dchub
local $| = 1; # unbuffered mode
select (PIPEOUT); #STDOUT Pufferung abschalten
$| = 1; # nicht erst bei programmende alles an Anna schicken !
#Pipe zu anna oeffnet, wobei ein lesender/schreibender Zugriff gewnscht wird
#unlink ("/home/thomas/olaf/anna/output.txt");
# Alte anworten loeschen
unlink ("/home/thomas/olaf/anna/output.txt");
# j-alice als nice level starten, und ausgaben an output.txt leiten
# dazu ein eingabe Pipe ffnen, um fragen an anne stellen zu koennen
open(PIPEOUT, "| nice ./j-alice > output.txt");
print ("j-alice gestartet...");
sleep(20); # erstmal anna in ruhe starten lassen
# Alte Frage loeschen
unlink ("/home/thomas/olaf/anna/input.txt");
unlink ("/home/thomas/olaf/anna/last_input.txt");
$i = 1;
while($i < 5)
{
if (-e "/home/thomas/olaf/anna/input.txt")
{
# Gestellte Frage auslesen und anna stellen
open (INFILE, "</home/thomas/olaf/anna/input.txt");
flock (INFILE, 2);
$meinefrage = <INFILE>;
close INFILE;
print PIPEOUT "$meinefrage\n";
# Alte Frage loeschen
unlink ("/home/thomas/olaf/anna/input.txt");
}
else
{
sleep(1);
}
}
print ("j-alice beenden...");
system `killall j-alice`;
Und das script zum einbinden in Opendchub:
# General Chat with the KI Anna, uses two scripts,
# this one and abfrage.pl, thats runs in background
# in verbindung mit opendchub. Wartet auf eine Frage und schreibt
# sie in die Datei input.txt. und gibt die antwort von der KI Anna nach
# opendchub aus.
# input.txt - aktuelle frage
# last_input.txt - alle fragen dieser session als log, um bei abstuerzen
# - den fehler finden zu koenne
# output.txt - antworten von anna
# abfrage.pl - zweiter script fuer anna
$botname = "Anna";
sub main ()
{
odch::register_script_name($botname);
}
sub data_arrival()
{
my($user,$data)=@_;
if($data =~ /[Aa]nna/)
{
$data =~ tr/!/./; # anna vertraegt keine !
$Zahl = index($data,">");
$data = substr($data, $Zahl+2);
$data = substr($data,0,length($data)-1);
if($data =~ /GetINFO/)
{
}
else
{
open(file, ">/home/thomas/olaf/anna/input.txt");
open(logfile, ">>/home/thomas/olaf/anna/last_input.txt");
print file $data;
print logfile $data;
close (file);
close (logfile);
sleep (2);
if (-e "/home/thomas/olaf/anna/input.txt")
{
odch::data_to_all("<Anna> I'am away.|");
# anna reagiert nicht, also nicht antworten
}
else
{
$output_string = `tail -n2 /home/thomas/olaf/anna/output.txt | grep Anna | cut -d \\> -f 3`;
# CR entfernen am ende
$output_string = substr($output_string,0,length($output_string)-1);
odch::data_to_all("<Anna> $output_string|");
return;
}
}
}
}