Gunther: Cron Job PHP Skript für Disk Usage/Free

Hallo werte Selfgemeinde,

ich muss mich mal wieder als Linux Noob outen.
Wie stelle ich es an, dass ich ein PHP Skript ausführen lassen kann (per Cron), dass mir die Ausgabe von 'df -h /' zur "Weiterverarbeitung" bereitstellt?

Ziel ist es, die Werte von 'df' in einer MySQL DB zu speichern, damit sie in einer anderen Anwendung zur Verfügung stehen.

Ich hoffe, ich konnte mein Anliegen halbwegs verständlich formulieren?

Für eure freundliche Unterstützung wie immer meinen besten Dank im Voraus!

Gruß Gunther

  1. Meine Herren!

    Wie stelle ich es an, dass ich ein PHP Skript ausführen lassen kann (per Cron), dass mir die Ausgabe von 'df -h /' zur "Weiterverarbeitung" bereitstellt?

    An welcher Stelle hast du denn das Problem? Beim Einrichten des Cronjobs oder beim Implementieren des PHP-Skriptes?

    Um shell-Kommandos auszuführen bietet PHP eine ganze Reihe an Werkzeugen:

    shell_exec,
    Backstick-Operator: ''
    exec,
    passthru

  2. Tach!

    Wie stelle ich es an, dass ich ein PHP Skript ausführen lassen kann (per Cron), dass mir die Ausgabe von 'df -h /' zur "Weiterverarbeitung" bereitstellt?

    Unter den Program Execution Functions gibt es mindestens eine, die die gesamte Ausgabe des gestarteten Programs zur Verfügung stellt. (Da gibts auch eine, die nur die letzte Zeile liefert.) Der Rest ist Stringverarbeitung.

    Das Ausführen per Cronjob ist auch nicht schwer, du musst da sowas aufrufen: /pfad/zu/php /pfad/zur/datei.php

    Ziel ist es, die Werte von 'df' in einer MySQL DB zu speichern, damit sie in einer anderen Anwendung zur Verfügung stehen.

    Die Frage ist, warum du da über df -h gehen möchtest und nicht mit PHPs disk_free_space() und Co. die genauen Werte (von den dich interessierenden Partitions) ermittelst. Vielleicht heißt die Lösung auf das eigentlichen Problem auch Munin.

    dedlfix.

  3. Hallo,

    vielen Dank dedlfix und 1UnitedPower für eure Antworten.
    Mit der PHP-Variante und 'shell_exec()' bin ich soweit schon mal klar.

    Zusatzfrage:
    Mir ist gerade aufgefallen, dass es einfacher wäre, wenn ich den Output von 'df -h /' einfach in eine Datei schreiben lassen würde.

    Kann ich dann nicht einfach das Ganze in ein Shell Skript packen?
    Wo "gehört" das unter Debian Wheezy dann hin?
    Wie sorge ich dafür, dass die Datei bei jedem Aufruf überschrieben/ neu erstellt wird (und nicht an die vorhandene Datei angehängt wird)?

    Gruß Gunther

    1. Meine Herren,

      Mir ist gerade aufgefallen, dass es einfacher wäre, wenn ich den Output von 'df -h /' einfach in eine Datei schreiben lassen würde.

      Suchst du vielleicht nach:

      df -h > output.txt

      Mit > kannst du die Standardausgabe umleiten.

      1. Mein Herr,

        Mir ist gerade aufgefallen, dass es einfacher wäre, wenn ich den Output von 'df -h /' einfach in eine Datei schreiben lassen würde.

        Suchst du vielleicht nach:

        df -h > output.txt

        Mit > kannst du die Standardausgabe umleiten.

        Ja, das passt schon mal.
        Wenn du mir jetzt noch verraten kannst, wo ich das Skript am besten ablege, sodass es nur von 'root' ausgeführt werden kann, wäre mir sehr geholfen - danke!

        Gruß Gunther

        1. Tach!

          Wenn du mir jetzt noch verraten kannst, wo ich das Skript am besten ablege, sodass es nur von 'root' ausgeführt werden kann, wäre mir sehr geholfen - danke!

          Nur von root auszuführen, geht auch über passende Berechtigungen, egal wo es liegt. Aber generell gibt es /usr/local mit einer ähnlichen Struktur wie unter /usr selbst. Dort kann man Zeug ablegen, das nicht von der Distribution installiert wird. Da kann aber auch jeder lesen und /usr/local/bin sowie /usr/local/sbin sollten auch bei Normalsterblichen im PATH stehen. Also siehe ersten Satz dieses Abschnitts. Alternativ geht auch noch sowas wie /root/bin/, was aber nicht unbedingt im PATH vom root sein muss. Aber du willst das ja gar nicht zu Fuß aufrufen sondern über Cron, und da gibt man sowieso besser volle Pfade an, und dann ist der Liegeplatz im Prinzip auch egal.

          dedlfix.

          1. Tach!

            Nur von root auszuführen, geht auch über passende Berechtigungen, egal wo es liegt. Aber generell gibt es /usr/local mit einer ähnlichen Struktur wie unter /usr selbst. Dort kann man Zeug ablegen, das nicht von der Distribution installiert wird. Da kann aber auch jeder lesen und /usr/local/bin sowie /usr/local/sbin sollten auch bei Normalsterblichen im PATH stehen. Also siehe ersten Satz dieses Abschnitts. Alternativ geht auch noch sowas wie /root/bin/, was aber nicht unbedingt im PATH vom root sein muss. Aber du willst das ja gar nicht zu Fuß aufrufen sondern über Cron, und da gibt man sowieso besser volle Pfade an, und dann ist der Liegeplatz im Prinzip auch egal.

            Ja, danke.
            Soweit war ich mit meinen Recherchen auch schon gekommen. Habe jetzt das folgende Skript "diskfree.sh" in '/usr/local/bin' abgelegt:

              
            #!/bin/bash  
            df -h /  
            
            

            Und folgenden Cron Eintrag:

              
            PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin  
            */5 * * * *	root /usr/local/bin/diskfree.sh > /[Pfad]/diskfree.txt  
            
            

            Wobei [Pfad] der Pfad auf meinem Server ist.

            Passieren tut aber "nix".

            Irgendein Fehler drin?

            Wie kann ich das denn am besten debuggen?

            Gruß Gunther

            1. Tach!

              Und folgenden Cron Eintrag:

              PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
              */5 * * * * root /usr/local/bin/diskfree.sh > /[Pfad]/diskfree.txt

              
              > Passieren tut aber "nix".  
              > Irgendein Fehler drin?  
                
              Ist das Script ausführbar? Hat es eine korrekte Shebang?  
                
              
              > Wie kann ich das denn am besten debuggen?  
                
              Logfiles vom Cron oder allgemeines Logfile (var/log/messages oder /var/log/syslog oder was auch immer deine Distribution oder Konfiguration macht - jedenfalls mal in /var/log/ rumschauen) wären Anlaufstellen.  
                
                
              dedlfix.
              
              1. Tach!

                Und folgenden Cron Eintrag:

                PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
                */5 * * * * root /usr/local/bin/diskfree.sh > /[Pfad]/diskfree.txt

                
                > > Passieren tut aber "nix".  
                > > Irgendein Fehler drin?  
                >   
                > Ist das Script ausführbar? Hat es eine korrekte Shebang?  
                  
                Ja, über die Konsole aufgerufen funktioniert es => Fehler im Cron.  
                  
                
                > > Wie kann ich das denn am besten debuggen?  
                >   
                > Logfiles vom Cron oder allgemeines Logfile (var/log/messages oder /var/log/syslog oder was auch immer deine Distribution oder Konfiguration macht - jedenfalls mal in /var/log/ rumschauen) wären Anlaufstellen.  
                  
                

                ERROR (Missing newline before EOF, this crontab file will be ignored)

                Wie blöd kann man sein ..., jetzt funktioniert es soweit.  
                  
                Noch eine abschließende Frage:  
                Da das Skript ja unter 'root' ausgeführt wird, gehört auch die erzeugte Datei root (mit 0644). Kann ich das "irgendwie" ändern?  
                  
                  
                Gruß Gunther
                
                1. Tach!

                  Ja, über die Konsole aufgerufen funktioniert es => Fehler im Cron.

                  Es scheint ja jetzt zu laufen, aber trotzdem dazu noch ein kleiner Hinweis: Dass ein Script direkt ausgeführt funktioniert, ist schon viel wert, aber das heißt noch nicht, dass es als Cron-Script ebenfalls läuft. Der Cron stellt üblicherweise einen anderen PATH zur Verfügung als die Kommandozeile und dann findet das Script seine Programme nicht. Deshalb ist es günstig, alle Programme mit vollem Pfad aufzurufen - und vielleicht für den Aufruf eine Variable zu erstellen, so dass man bei Bedarf den Pfad nur an einer Stelle ändern muss und nicht im ganzen Script.

                  dedlfix.

                  1. Tach!

                    Ja, über die Konsole aufgerufen funktioniert es => Fehler im Cron.

                    Es scheint ja jetzt zu laufen, aber trotzdem dazu noch ein kleiner Hinweis: Dass ein Script direkt ausgeführt funktioniert, ist schon viel wert, aber das heißt noch nicht, dass es als Cron-Script ebenfalls läuft. Der Cron stellt üblicherweise einen anderen PATH zur Verfügung als die Kommandozeile und dann findet das Script seine Programme nicht. Deshalb ist es günstig, alle Programme mit vollem Pfad aufzurufen - und vielleicht für den Aufruf eine Variable zu erstellen, so dass man bei Bedarf den Pfad nur an einer Stelle ändern muss und nicht im ganzen Script.

                    Ja, es läuft jetzt - danke!
                    Und ich hab' doch den kompletten Pfad angegeben!?

                    Ich hätte da aber gleich das nächste Problem ...!

                    Und zwar möchte ich per Bash Skript ein PHP Skript aufrufen.
                    Dazu folgender Code:

                      
                    #!/bin/bash  
                    /usr/bin/php5 -q /[Pfad zum Skript]/cronjob.php  
                    
                    

                    Soweit scheint das auch zu laufen, wenn ich es per

                      
                    <?php  
                    $out = shell_exec('/usr/local/bin/runcron.sh');  
                    echo trim($out);  
                    ?>  
                    
                    

                    aufrufe.

                    Das Problem ist aber, dass da noch ein Parameter '--force' mit dazu muss, damit das Skript auch das macht, was es soll. Und daran scheitere ich bisher. Entweder passiert "gar nichts" beim Aufruf, oder ich erhalte einen 500er.

                    Irgendeinen Tipp?

                    Gruß Gunther

                    1. Tach!

                      Das Problem ist aber, dass da noch ein Parameter '--force' mit dazu muss, damit das Skript auch das macht, was es soll. Und daran scheitere ich bisher. Entweder passiert "gar nichts" beim Aufruf, oder ich erhalte einen 500er.

                      Ein 500er kann alles sein. Der Text ist bewusst nichtssagend gehalten. Da musst du schon ins Error-Log schauen, um die genaue Ursache zu sehen.

                      dedlfix.

                      1. Tach!

                        Ein 500er kann alles sein. Der Text ist bewusst nichtssagend gehalten. Da musst du schon ins Error-Log schauen, um die genaue Ursache zu sehen.

                        Jo, aber mit der Fehlermeldung kann ich nicht wirklich etwas anfangen:

                          
                        [error] [client xxx.xxx.xxx.xxx] (104)Connection reset by peer: FastCGI: comm with server "/var/www/php5-fpm/froxlor.panel/[Hostname]/32d8.ssl-fpm.external" aborted: read failed  
                        [error] [client xxx.xxx.xxx.xxx] FastCGI: incomplete headers (0 bytes) received from server "/var/www/php5-fpm/froxlor.panel/[Hostname]/32d8.ssl-fpm.external"  
                        
                        

                        Also falls du dazu eine Idee hast ...!?

                        Gruß Gunther

                        1. Tach!

                          [error] [client xxx.xxx.xxx.xxx] (104)Connection reset by peer: FastCGI: comm with server "/var/www/php5-fpm/froxlor.panel/[Hostname]/32d8.ssl-fpm.external" aborted: read failed
                          [error] [client xxx.xxx.xxx.xxx] FastCGI: incomplete headers (0 bytes) received from server "/var/www/php5-fpm/froxlor.panel/[Hostname]/32d8.ssl-fpm.external"

                            
                          Das FastCGI hat keine vollständige HTTP-Response bekommen, da ist irgendwas gestorben beim Verarbeiten. Mehr kann ich dazu leider nicht sagen. Aber du kannst mal versuchen - am besten in der zuständigen php.ini -, das error\_reporting auf E\_ALL zu setzen (display\_errors ist egal), log\_errors auf on und das error\_log auf eine beschreibbare Datei zu konfigurieren. Vielleicht steht da dann mehr drin.  
                            
                            
                          dedlfix.
                          
                        2. Mahlzeit,

                          und was passiert, wenn du das PHP-Script nicht im Browser sondern in der Kommandozeile aufrufst?

                          --
                          42