Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. JavaScript
    5. Dateien kopieren mit Fehlerauswertung stdout,stderr,error

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Dateien kopieren mit Fehlerauswertung stdout,stderr,error

    This topic has been deleted. Only users with topic management privileges can see it.
    • MartinSU
      MartinSU last edited by MartinSU

      Hallo,

      ich kopiere Nachts um 00:30 das History Verzeichnis auf meine NAS sowie zu anderen Zeiten auch andere Dateien.
      Blockly.gif
      Nach dem Kopieren überprüfe ich, ob das Verzeichnis/Datei am Ziel existiert und ob der Zeitstempel von Quelle und Ziel übereinstimmt.
      Im Prinzip klappt das auch sehr gut. Aber in unregelmäßigen Abständen (3-6 mal im Monat) gibt es von meiner Prüfroutine eine Fehlermeldung: "Kopierfehler...." (weil Zieldatei nicht existiert)
      Jetzt wollte ich der Sache etwas genauer auf die Spur gehen.
      Hier meine Routine, der Aufruf ist ein Blockly, das eigentliche geschieht mit einer Javascript-Funktion.
      Die eigentliche Kopier-Routine am Ende muss per SSH aufgerufen werden, wegen den Zugriffsrechten.

      function (sQ, sZ, sInfo)
      var sStr, befehl, result1, result2, result3;
      var SSH = require('simple-ssh');
      var ssh = new SSH({
          host: '127.0.0.1',
          user: 'myuser',
          pass: 'mypass'
      });
      // Prufe ob NAS gemountet ist
      sStr = '';
      exec('mount | grep /mnt/NAS', async (error, result, stderr) => {
          sStr = result;
          console.info('mount | grep result: ' + result ); // ==> leer
          console.info('mount | grep stderr: ' + stderr ); // ==> leer
          console.info('mount | grep error: ' + error );   // ==> Error: Command failed: mount | grep /mnt/NAS_FB at ....
      
          // falls nicht gemountet => mount
          if (!String(sStr).includes('/mnt/NAS')) 
          {
              console.info('====== mount NAS ======');
              exec('sudo mount -t cifs //192.168.xxx.xxx/Pfad/ und so weiter /mnt/NAS', async (error, result, stderr) => 
                  {
                      console.info('mount result: ' + result ); // ==> leer
                      console.info('mount stderr: ' + stderr ); // ==> leer
                      console.info('mount error: ' + error );   // ==> 'null'
                 });
          }
          else
          {
              console.info('====== NAS existiert ======');
          }
          await wait(300);
          result1 = 'leer';
          result2 = 'leer';
          result3 = 'leer';
      
          befehl = ['sudo cp -a ',sQ, ' ', sZ].join('');
          console.info( befehl );   // ==> Ausgabe: sudo cp -a /opt/iobroker/iobroker-data/Pruf_LOG.txt /mnt/NAS/ioBroker/Test/
          ssh.exec( befehl, async (error, result, stderr) => {
              console.info('befehl result: ' + result ); // ==> keine Ausgabe
              console.info('befehl stderr: ' + stderr ); // ==> keine Ausgabe
              console.info('befehl error: ' + error );   // ==> keine Ausgabe
          }).start();
          // =========> Datei ist kopiert, aber keine Ausgabe von result, stderr, error !!!!!
      
          *** Alternativer Versuch ***
          ssh.exec( befehl, { out: function( stdout, stderr, error ) {
              console.info('befehl result: ' + result ); // ==> keine Ausgabe
              result1 = result;
              console.info('befehl stderr: ' + stderr ); // ==> keine Ausgabe
              result2 = stderr;
              console.info('befehl error: ' + error );   // ==> keine Ausgabe
              result3 = error;
          },}).start();
          // =========> Datei ist kopiert, aber keine Ausgabe von result, stderr, error !!!!!
          
          console.info(result1);   // ==> "leer"
          console.info(result2);   // ==> "leer"
          console.info(result3);   // ==> "leer"
      });
      

      Meine Vermutung ist, dass ich bei dem SSH als anderer User unterwegs bin und somit keine Ausgabe erscheint.
      Ich habe auch versucht, das Ergebnis auf Variablen zu kopieren und später (wenn SSH vorbei) auszugeben, aber alle 3 sind "leer"
      Getestet habe ich auch schon statt >>sudo cp -a ',sQ, ' ', sZ<< den Befehl >>sudo rsync -rt ',sQ, ' ', sZ<< , Datei wurde kopiert auch aber keine Ausgaben.
      Wie erhalte ich die stdout, stderr, error um meinen Kopierfehler auszuwerten?
      Oder gibt es einen anderen Weg Dateien/Verzeichnisse zu kopieren? Mit Fehlerausgabe/Auswertung?
      Vielleicht eleganter?
      Eine Sache interessiert mich noch: Wie bekomme ich heraus, ob der Kopiervorgang abgeschlossen / fertig ist? Gerade bei dem History-Verzeichnis kann dass schon mal ein paar Sekunden dauern.
      Danke

      haus-automatisierung 1 Reply Last reply Reply Quote 0
      • haus-automatisierung
        haus-automatisierung Developer Most Active @MartinSU last edited by haus-automatisierung

        @martinsu sagte in Dateien kopieren mit Fehlerauswertung stdout,stderr,error:

        Ich habe auch versucht, das Ergebnis auf Variablen zu kopieren und später (wenn SSH vorbei) auszugeben, aber alle 3 sind "leer"

        So läuft das nicht. SSH ist dann nicht "vorbei". Du arbeitest ja mit Callbacks. Der ssh.exec wird nur gestartet und direkt danach wird die Logik weiter ausgeführt. Da wartet keine Funktion auf eine andere. Dafür gibt es ja Promises (wenn man das Verhalten möchte).

        @martinsu sagte in Dateien kopieren mit Fehlerauswertung stdout,stderr,error:

        Wie erhalte ich die stdout, stderr, error um meinen Kopierfehler auszuwerten?

        Das steht ja in der Doku. Error ist eine separate Option neben out: https://github.com/MCluck90/simple-ssh?tab=readme-ov-file#api

        MartinSU 1 Reply Last reply Reply Quote 0
        • haus-automatisierung
          haus-automatisierung Developer Most Active last edited by

          Vorschlag (natürlich ungetestet):

          const SSH = require('simple-ssh');
          const ssh = new SSH({
              host: '127.0.0.1',
              user: 'myuser',
              pass: 'mypass'
          });
          
          // Prufe ob NAS gemountet ist
          exec('mount | grep /mnt/NAS', async (error, result, stderr) => {
              console.info('mount | grep result: ' + result);
              console.info('mount | grep stderr: ' + stderr);
              console.info('mount | grep error: ' + error);
           
              // falls nicht gemountet => mount
              if (!String(result).includes('/mnt/NAS')) {
                  console.info('====== mount NAS ======');
                  exec('sudo mount -t cifs //192.168.xxx.xxx/Pfad/ /mnt/NAS', async (error, result, stderr) => {
                      console.info('mount result: ' + result);
                      console.info('mount stderr: ' + stderr);
                      console.info('mount error: ' + error);
                 });
              } else {
                  console.info('====== NAS existiert ======');
              }
          
              // Eine frei erfundene Zeit warten ist nicht optimal, da das nicht garantiert, dass der Befehl auch abgeschlossen ist
              await wait(300);
          
              const befehl = `sudo cp -a ${sQ} ${sZ}`;
              console.info(befehl);
          
              ssh.exec(befehl, {
                  out: (stdout) => {
                      console.info('befehl result: ' + stdout);
                  },
                  err: (stderr) => {
                      console.info('befehl error: ' + stderr);
                  }
              }).start();
          });
          
          1 Reply Last reply Reply Quote 0
          • MartinSU
            MartinSU @haus-automatisierung last edited by

            @haus-automatisierung
            Das der ssh.exec() nur angestoßen wird, ist mir klar. Aber die Zeilen
            console.info('befehl result: ' + result ); // ==> keine Ausgabe usw.......
            müssten doch eigentlich ausgeführt werden, wenn der callback zurück kommt, oder? Da kommt aber auch keine Ausgabe.
            mit out, das habe ich wohl falsch verstanden und falsch angewendet.
            Ich habe nach Deinem Vorschlag dies hier probiert:

            befehl = ['sudo cp -a ',sQ, ' ', sZ].join('');
            ssh.exec( befehl, { 
                    out: ( stdout ) => {
                        console.info('befehl stdout: ' + stdout );
                    },
                    err: ( stderr ) => {
                        console.info('befehl stderr: ' + stderr );
                    }
                }).start();
            

            Dabei erhalte ich eine Fehlermeldung, obwohl die Datei kopiert ist (Berechtigungen werden beibehalten, ist das ein Fehler?)

            befehl stderr: cp: preserving permissions for ‘/mnt/NAS_FB/iobroker/Test/Pruf_LOG.txt’
            befehl stderr: : Operation not supported
            

            Wenn ich jetzt eine Datei kopiere, die es nicht gibt, kommt:

            befehl stderr: cp: cannot stat '/opt/iobroker/iobroker-data/Pruf_xLOG.txt'
            befehl stderr: : No such file or directory
            

            Stimmt soweit.

            Wie würdest Du denn Dateien/Verzeichnisse kopieren? Hast Du eine andere / bessere Lösung?

            OliverIO 1 Reply Last reply Reply Quote 0
            • OliverIO
              OliverIO @MartinSU last edited by OliverIO

              @martinsu
              Du kannst über eine nicht interaktive Verbindung kein sudo schicken.
              Normalerweise kommt ja dann die passwortabfrage, was ja etwas schwierig wird.
              Entweder vergibst du dem Remote Nutzer die entsprechende Berechtigung oder du konfigurierst
              Das auf entfernten Rechner

              https://wiki.ubuntuusers.de/sudo/Konfiguration/

              Der iobroker nutzt das selbst. Da kannst du dann an den in der Doku erwähnten Stellen diese Konfiguration findest.

              Bei einem copy Befehl dann eher ersteres

              Nachtrag
              Um von einem Rechner auf einen anderen Rechner was zu kopieren bietet sich rsync an. Der kann sehr viel.
              https://wiki.ubuntuusers.de/rsync/

              Den Sync dann einfach per cron (also der vom Betriebssystem) anstoßen.

              MartinSU 1 Reply Last reply Reply Quote 0
              • MartinSU
                MartinSU @OliverIO last edited by

                @oliverio
                den rysnc hatte ich auch schon probiert:

                befehl = ['sudo rsync -rt ',sQ, ' ', sZ].join('');
                ssh.exec( befehl, { 
                        out: ( stdout ) => {
                            console.info('befehl stdout: ' + stdout );
                        },
                        err: ( stderr ) => {
                            console.info('befehl stderr: ' + stderr );
                        }
                    }).start();
                

                leider kommt dann:
                befehl stderr: rsync: [receiver] rename "/mnt/NAS/iobroker/Test/Pruf_LOG.txt.l53NvH" -> "Pruf_LOG.txt": Permission denied (13)
                befehl stderr: rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1338) [sender=3.2.7]

                OliverIO 1 Reply Last reply Reply Quote 0
                • OliverIO
                  OliverIO @MartinSU last edited by OliverIO

                  @martinsu

                  Oh Mann.
                  Lese meinen ersten Post nochmal gaaaaanz genau durch.
                  Ganz speziell den Part wo ich das Wort sudo erwähnte.
                  Auch lese die Beschreibung von rsync mal genau durch,
                  Du scheinst die Funktionsweise noch nicht ganz verstanden haben.
                  Woher soll dieser Befehl den nun wissen von wo nach wohin er da was kopieren soll? Auch würde ich ihn nicht mit ssh ausführen. Rsync kann selbst ssh und wendet das beim kopieren auch an, wenn du die richtigen Parameter angibst.

                  Alle Befehle des JavaScript Adapters werden mit dem Benutzer iobroker auf dem lokalen Rechner ausgeführt.
                  Ausprobieren kannst du die shellbefehle wenn du auf der Konsole

                  sudo -u iobroker bash
                  

                  Ausführst. Dann bist du mit der Berechtigung iobroker unterwegs und du kannst rsync oder ssh ausprobieren.

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post

                  Support us

                  ioBroker
                  Community Adapters
                  Donate

                  942
                  Online

                  31.8k
                  Users

                  80.0k
                  Topics

                  1.3m
                  Posts

                  3
                  7
                  190
                  Loading More Posts
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes
                  Reply
                  • Reply as topic
                  Log in to reply
                  Community
                  Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                  The ioBroker Community 2014-2023
                  logo