Device Ausgabe auf anderes Device umleiten

  • Hallo zusammen,


    folgende Frage: Kann man die Ausgabe eines Devices z.B. /dev/xy1 umleiten auf ein anderes Device z.B. /dev/xy2 ? D.h. alle ankommenden Nachrichten gehen dann auf beide Devices.
    Wenn ja, wie geht sowas?


    Grüße
    Fux

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

    Einmal editiert, zuletzt von Fux ()

  • Zitat

    Original von Fux
    Kann man die Ausgabe eines Devices z.B. /dev/xy1 umleiten auf ein anderes Device z.B. /dev/xy2 ?


    Alles, was von /dev/xy1 kommt, nach /dev/xy2?! Oder doch eher ...


    Zitat

    D.h. alle ankommenden Nachrichten gehen dann auf beide Devices.


    ... alles, was von STDIN o.ä. kommt, nach /dev/xy1 und /dev/xy2 leiten? man tee -> echo bla | tee /dev/xy1 >/dev/xy2

  • Hab mir den "tee" Befehl mal angeschaut, nur leider ist der nur fürs STDIN Device :(
    Ich bräucht so einen Befehl wie tee wo ich das Input Device selbst wählen könnte. Ach ja ich hab mich vielleicht im ersten Satz bißchen zweideutig ausgedrückt. Also die Ausgabe soll schon auf beiden Devices dann erfolgen.

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

  • Hi!
    Ich glaube,
    du solltest uns eröffnen was genau du vorhast,
    weil Devicefiles kann man in vielen Fällen nicht einfach so kopieren
    einfügen etc. wie man es mit Dateien machen kann.


    Gruß,
    Henning

    --==Mein neuer VDR läuft: DH102, Athlon64 X2 4850e, 1TB Samsung, Asus M2A-VM HDMI, 2 GB DDR2-800, 80+ Netzteil, TT DVB-S 1.6-4MB & Skystar II==--

    --==VDR 1.6.0-2, HgDVB, ACPI Wakeup, xineliboutput und graphtft auf X mit xf86-video-ati (DualHead / XVideo / DRI) ausm GIT auf Debian Lenny mit Kernel 2.6.28-rc6 ==--

  • Also :) das ganze gehört für meine Linux MP3-Box


    Ich habe ein Perl-Skript welches die Kommandos von /dev/lirc auswertet. Außerdem hab ich einen Kernel Patch der mir bestimmte Tasten auf ein spezielles Device namens /dev/funkey umleitet. Das Perl-Skript wartet in einer Endlosschleife immer bis an das /dev/lirc eine Info anliegt (wenn man das so sagen kann?) und macht erst dann weiter. Und das Skript soll eben jetzt auch Infos von /dev/funkey und nicht nur von /dev/lirc auswerten.


    Was mich generell interessieren würde, bzw. ein Problem welches ich schön öfter hatte: Wie schaff ich es, daß zwei (z.B.Perl) Skripte miteinander kommunizieren. Muß ich mich dazu mit Sockets beschäftigen oder ist das auch einfacher zu lösen. Hat da vielleicht jemand einen guten Link zur Hand?


    Grüße
    Fux

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

    2 Mal editiert, zuletzt von Fux ()

  • Erstmal prinzipiell dazu ...


    Zitat

    Original von Fux
    Hab mir den "tee" Befehl mal angeschaut, nur leider ist der nur fürs STDIN Device :(
    Ich bräucht so einen Befehl wie tee wo ich das Input Device selbst wählen könnte.


    tee /dev/xy1 >/dev/xy2 </dev/MeineAlternativesSTDIN

  • Zitat

    Original von Fux
    Ich habe ein Perl-Skript welches die Kommandos von /dev/lirc auswertet. Außerdem hab ich einen Kernel Patch der mir bestimmte Tasten auf ein spezielles Device namens /dev/funkey umleitet. Das Perl-Skript wartet in einer Endlosschleife immer bis an das /dev/lirc eine Info anliegt (wenn man das so sagen kann?) und macht erst dann weiter. Und das Skript soll eben jetzt auch Infos von /dev/funkey und nicht nur von /dev/lirc auswerten.


    Du willst also von 2 Devices lesen ... dann schau dir mal das Perl-Modul IO::Select an. Sollte (zumindest bei aktuellen Versionen) im Standard-Perlpaket mit drin sein.

  • Jetzt ist mir noch ganz was anderes aufgefallen:


    srw-rw---- 1 root video 0 Mar 4 09:59 lircd
    ^
    crw-rw-rw- 1 music root 254, 0 Feb 17 01:26 funkey
    ^


    Das s ist ja ein socket, aber was bedeutet "c" ?
    Da kann ich connecten was ich will, da wirds wohl nicht funktionieren?


    EDIT:
    Ich schaffs generell unter Perl nicht mit /dev/funkey zu verbinden.
    So hab ichs versucht:
    $funkeySocket = '/dev/funkey'
    my $funkey = new IO::Socket::UNIX ($funkeySocket)
    Hab auch mal einige Optionen durchprobiert (Type,..) bringt auch nichts.


    Unter C schaut es folgendermassen aus (da läufts):

    Code
    funkey = open ("/dev/funkey", O_RDONLY);
    	if (funkey < 0) {
    		perror ("Cannot read /dev/funkey");
    		exit (1);
    	}
    	while (read (funkey, &buf, 1)) {
    		keypress (buf);
    	}
    	close (funkey);


    Was mach ich falsch?


    Grüße
    Fux

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

    3 Mal editiert, zuletzt von Fux ()


  • man ls -> "character special device"


    Darum lässt es sich auch nicht ...


    Zitat

    EDIT:
    Ich schaffs generell unter Perl nicht mit /dev/funkey zu verbinden.
    So hab ichs versucht:
    $funkeySocket = '/dev/funkey'
    my $funkey = new IO::Socket::UNIX ($funkeySocket)
    Hab auch mal einige Optionen durchprobiert (Type,..) bringt auch nichts.


    ... als UNIX Socket ansprechen.


    Zitat

    Unter C schaut es folgendermassen aus (da läufts):

    Code
    funkey = open ("/dev/funkey", O_RDONLY);
    	if (funkey < 0) {
    		perror ("Cannot read /dev/funkey");
    		exit (1);
    	}
    	while (read (funkey, &buf, 1)) {
    		keypress (buf);
    	}
    	close (funkey);


    Was mach ich falsch?


    Du machst es unter Perl nicht genauso. :D

    Code
    open($funkey, "<", "/dev/funkey") or die "Cannot read /dev/funkey";
    while (read($funkey, $buf, 1)) {
    	keypress($buf);
    }
    close($funkey);


    HTH

  • So, inzwischen hab ichs geschafft von zwei Quellen mit dem IO::Select Modul zu lesen. Danke für den Hinweis.


    Jedoch bekomm ich von /dev/funkey was rein, aber er zeigt mir nicht was bzw. es kommt nichts vernünftiges rein. Nur immer: ""


    Hab das unter anderem so ausgewertet:
    $lircline = read($funkey, $buf, 1);
    print "funkey1=$lircline\n";
    $lircline = $buf;


    Gibts da keine Methode das ähnlich auszuwerten wie vom /dev/lirc
    (da wirds einfach so gemacht: $lircline = <$lirc> wobei $lirc=new IO::Socket::UNIX( $lircSocket)) . Vermutlich brauch ich hier immer ein Newline Zeichen am Ende, oder? Wann genau nimmt man denn diese "Klammern": < ... > her?


    Gruß
    Fux

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5


  • Huh?! ?(


    Code
    greywolf@matrix:/tmp$ perldoc -f read
           read FILEHANDLE,SCALAR,LENGTH,OFFSET
           read FILEHANDLE,SCALAR,LENGTH
                   Attempts to read LENGTH characters of data into
                   variable SCALAR from the specified FILEHANDLE.
                   Returns the number of characters actually read, 0
                   at end of file, or undef if there was an error (in
                   the latter case $! is also set).
    [..]


    read-Funktion falsch verstanden?


    Geht aber wohl trotzdem etwas schief, wenn $lircline keine Zahl enthält (also undef ist) ... lass mal $! ausgeben. Ist $funkey auf non-blocking-IO gestellt? Dann sind evtl. einfach gerade keine Daten verfügbar.


    Zitat

    Gibts da keine Methode das ähnlich auszuwerten wie vom /dev/lirc
    (da wirds einfach so gemacht: $lircline = <$lirc> wobei $lirc=new IO::Socket::UNIX( $lircSocket)) . Vermutlich brauch ich hier immer ein Newline Zeichen am Ende, oder? Wann genau nimmt man denn diese "Klammern": < ... > her?


    Um zeilenweise zu lesen: man perlop -> "I/O Operators". Dürfte für abwechselndes Lesen aus mehreren Dateien wenig geeignet sein ...

  • Also die READ-Funktion hab ich schon kapiert. Ich erhalte zu folgendem Code


    Code
    $lircline = read($funkey, $buf, 1);
    		print "\$!=$!\n";
    		print "funkey1=$lircline\n";
    		$lircline = $buf;
    		print "funkey2=$lircline\n";
    		print "jetzt funkeyKommando\n";


    Ausgaben:
    $!=
    funkey1=1
    funkey2=


    Zitat


    variable SCALAR from the specified FILEHANDLE.
    Returns the number of characters actually read


    SCALAR entspricht bei mir funkey1 und der hat den Wert 1 bei mir. Es muß also was angekommen sein. Nur ich bekomm eben keinen Wert. $! ergibt auch nichts.

    Zitat

    Ist $funkey auf non-blocking-IO gestellt?


    Hmm, wie krieg ich das raus?

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

    3 Mal editiert, zuletzt von Fux ()

  • Zitat

    Original von Fux
    Also die READ-Funktion hab ich schon kapiert.


    Ok :) Sah so aus, als ob Du in $lircline die Daten erwartet hättest.


    Zitat

    Ausgaben:
    $!=
    funkey1=1
    funkey2=



    SCALAR entspricht bei mir funkey1 und der hat den Wert 1 bei mir. Es muß also was angekommen sein. Nur ich bekomm eben keinen Wert. $! ergibt auch nichts.


    Das war im ersten Beispiel aber noch nicht der Fall, da war funkey1 ja leer.
    Was "kommt" denn aus /dev/funkey? Wird wohl gerade irgendein nicht-druckbares Zeichen sein, denn laut read wurde ja ein Byte in $buf geschrieben. Schau Dir halt man den ASCII-Code an:


    Code
    printf("buf = %s\n",length($buf) ? ord($buf) : "(leer)");


    Zitat


    Hmm, wie krieg ich das raus?


    Code
    use Fcntl;
    
    
    [..]
    
    
    fcntl($funkey, F_GETFL, $flags) or die "fcntl(): $!";
    printf("blocking = %s\n",($flags & O_NONBLOCK) ? "no" : "yes");


    Standard ist AFAIK immer "blocking", wenn man es nicht beim open() oder via fcntl() explizit umstellt.

  • Spitze VOLLtreffer!

    Zitat

    Das war im ersten Beispiel aber noch nicht der Fall, da war funkey1 ja leer. Was "kommt" denn aus /dev/funkey? Wird wohl gerade irgendein nicht-druckbares Zeichen sein, denn laut read wurde ja ein Byte in $buf geschrieben. Schau Dir halt man den ASCII-Code an: code: 1: printf("buf = %s\n",length($buf) ? ord($buf) : "(leer)");


    Hab jetzt überprüft was für ein Code das auf dem /dev/funkey kommt: unsigned char und zwar als Hexzahl. Mit der Printformatierung auf ASCII kommt dann der entsprechende Wert in Dezimal raus. Wobei beim raufdrücken genau der Wert rauskommt der kommen soll und beim loslassen der Taste dieser Wert + 128(dezi).


    Mit ord($buf) kann ich das dann auch in der Routine weiterverarbeiten :)
    Mir fällt da zwar noch was ein, aber für heut solls mal gut sein ;)


    Vielen Dank!


    PS: Was macht den der ord() Befehl genau?
    PS2: Hast Du vielleicht eine gute Befehlsübersicht für Perl (Link) ?
    Hab jetzt schon etliche Sachen ausgedruckt, aber was richtig gutes hab ich noch nicht gefunden.

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

  • Zitat

    Original von Fux
    Spitze VOLLtreffer!


    Schön zu hören. :)


    Zitat

    PS: Was macht den der ord() Befehl genau?


    Na er gibt den Wert des ersten Zeichens im übergebenen String als Dezimalzahl zurück. Siehe perldoc -f ord


    Zitat

    PS2: Hast Du vielleicht eine gute Befehlsübersicht für Perl (Link) ?


    man perlfunc ... oder man perl, um noch von diversen anderen Perl man-pages zu erfahren (Parameter, Operatoren, FAQs ... siehe man page halt ;) )


    Zitat

    Hab jetzt schon etliche Sachen ausgedruckt, aber was richtig gutes hab ich noch nicht gefunden.


    Mit dem "Perl Kochbuch" bin ich ganz zufrieden (mein einziges Perl-Buch) ... kostet nur halt ein paar Euro, sind dafür aber diverse nette Codebeispiele drin (z.B. auch "Lesen aus vielen Dateihandles ohne Blocking" mittels select :D )

  • Jetzt hab ich noch eine kleine Frage:
    Wie kann ich von Perl aus auf globale Systemvariablen zugreifen?


    Hier mein Beispiel:
    Hab mit export die Variable in der BASH global bekannt gemacht.
    Dann würd ich gerne in einem Perl Skript darauf zugreifen.


    Code
    BASH:
    export $anzeige=blabla
    
    
    PERL:
    $anz = system('echo $anzeige');


    Hier wird aber die Variable nicht nach $anz übernommen sondern es wird einfach der Inhalt von "echo $anzeige" auf der Konsole angezeigt.




    Schönen Sonntag noch
    Grüße
    Fux

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

  • Zitat

    Original von Fux
    Jetzt hab ich noch eine kleine Frage:
    Wie kann ich von Perl aus auf globale Systemvariablen zugreifen?


    man perlvar -> $ENV{'anzeige'}


    Zitat

    Hier mein Beispiel:
    Hab mit export die Variable in der BASH global bekannt gemacht.
    Dann würd ich gerne in einem Perl Skript darauf zugreifen.


    Code
    BASH:
    export $anzeige=blabla
    
    
    PERL:
    $anz = system('echo $anzeige');


    Hier wird aber die Variable nicht nach $anz übernommen sondern es wird einfach der Inhalt von "echo $anzeige" auf der Konsole angezeigt.


    perldoc -f system ... zurückgegeben wird der Exitcode, die Ausgabe geht einfach nach STDOUT. Um die Ausgabe in eine Variable zu bekommen nimmt man wie unter bash:


    Code
    $anz = `echo $anzeige`


    Siehe auch man perlop :D

  • Danke! Jetzt kann ich schon mal zugreifen, funktioniert zwar noch nicht ganz wie vorgestellt, aber das krieg ich schon noch hin :)


    Eine ganz andere grundlegende Frage: Ist es möglich dateiübergreifend auf Variablen zuzugreifen? D.h. zwei Skripte greifen auf die Variablen eines dritten Skriptes zu. Hab schon alles mögliche nachgegoogelt :rolleyes: aber nichts dazu gefunden.


    Gruß
    Fux

    Hardware: Asus M3N78-EM µATX GF 8300 | AMD Sempron 140 | Display VFD USB MDM166A | DVB-S2 TT-3600 USB | RAM 1 GB | WD20EARS 2 TB
    Software: yaVDR 0.5

  • "dateiübergreifend" = mehrere unabhängig laufende Perl-Prozesse?


    man perlipc :D


    Direkt geht's nur bei Threads (die zum selben Prozess gehören müssen) und die werden AFAIK auch erst ab Perl 5.8 unterstützt. Habe ich aber in Perl noch nie verwendet, z.B. vdrsync benutzt es aber wohl für irgendwas.


    Um nur Code aus einer weiteren Perl-Datei einzubinden (z.B. für Funktionsdefinitionen) ohne einen neuen Prozess zu starten gibt es "do" (-> perldoc -f do)

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!