Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] ANSI Escape Sequenzen in Shell-Script

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] ANSI Escape Sequenzen in Shell-Script

    Hi,

    um meine tägliche Arbeit etwas zu beschleunigen, habe ich mir ein Shell-Script mit PHP geschrieben. Dieses Shell-Script ist interaktiv und verarbeitet die Eingabe bei jedem Tastendruck. Gelöst ist das so:

    PHP-Code:
    // set terminal to return single chars 
    `stty -icanon`;

    // set terminal to hide input
    `stty -echo`;

    // main loop
    while ($c fread(STDIN1)) {
        ... 
    mache irgendetwas

    Einzelne Tastatureingaben kriege ich damit, nur halt Escape-Sequenzen nicht. Ich kann zwar nach [ESC] dann das "[" auslesen und weiß dann, dass danach die eigentliche Anweisung kommt, allerdings können die Escape-Sequenzen ja unterschiedliche Längen haben. Und somit weiß ich dann nicht, wie weit ich lesen muss.

    Gibt es eine Möglichkeit, die Sequenz auszulesen, ohne dass ich alle bekannten Sequenzen zum Abgleich irgendwo hinterlegen muss?

    Danke und Gruß,
    Christoph

  • #2
    Na dann mal viel Freude. So ziemlich jede Terminalemulation kocht da gern mal ihr eigenes Süppchen.

    Prinzipiell kommst Du auf die Art hier zumindest auf der echten Konsole schon mal ganz gut weiter:

    PHP-Code:
    function handleRegularKey($character)
    {
      echo 
    "Hey, somebody pressed the key for \"{$character}\"\n";
    }

    function 
    handleEscape($sequence)
    {
      static 
    $i=0;
      switch(
    $sequence)
      {
        case 
    '1b 5b 44'$ev='LEFT BUTTON';break;
        case 
    '1b 5b 43'$ev='RIGHT BUTTON';break;
        case 
    '1b 5b 42'$ev='DOWN BUTTON';break;
        case 
    '1b 5b 41'$ev='UP BUTTON';break;
        default: 
    $ev=$sequence;break;
      }
      echo 
    '#',$i++,": got button event: {$ev}\n";
    }

    // main loop 
    while ($c fread(STDIN1)) { 
       
    // Wenn ESC:
       
    if($c==chr(27)){
         
    $escBuffer'1b';
         
    $ctrl=false;
         
    $cnt=0;

         do{
           
    $oc=ord(fread(STDIN,1));
           
    $cnt++;
           
    // Wenn Kontroll-Sequence
           
    if($cnt==&& $oc==0x5b){
             
    $ctrl=true;
             
    $escBuffer.=' 5b';
             
    $oc=ord(fread(STDIN,1));
             
    $cnt++;
           }
           
    $escBuffer.=' '.dechex($oc);
           
    /*
             // 0x20 bis 0x2f sind Füllzeichen
             if($oc>=0x20 && $oc<=0x2f)
               echo 'Intermediate';
             // Bei Kontrollsequenzen sind die Zeichen 0x30 bis 0x3f als Parameter zu verstehen
             if($ctrl && $oc>=0x30 && $oc<=0x3f)
               echo 'Kontrollsequence parameter';
           */
           // Das letzte Zeichen für eine Kontrollsequenz liegt zwischen 0x40 und 0x7e
           // und bei normalen Sequenzen zwischen 0x30 und 0x7e
           
    if(((!$ctrl && $oc>=0x30) || ($ctrl && $oc>=0x40)) && $oc<=0x7e)
             break;
         }while(
    true);
         
    // Alle Zeichen der Escape-Sequenz wurden verarbeitet, also kann der Handler 
         // aufgerufen werden.
         
    handleEscapeSequence($escBuffer);     
       }else{
         
    handleRegularKey($c);
       }

    (Achtung - ungetestet und nur aus nem Code von vor ewigen Zeiten portiert.)

    Gruß Jens

    Kommentar


    • #3
      Klasse Antwort, werd ich gleich mal testen, danke!

      Kommentar

      Lädt...
      X