2017-12-21 13 views
1

Ziemlich neu für Perl. Ich habe ein Perl-Skript auf einem Linux-Rechner, der eine eigene Logdatei hat. Der Name der Protokolldatei kann sich ändern, abhängig von den Daten, an denen das Skript arbeitet (Datum, Dateiname, Datentyp usw.)Perl-Skript gibt STDOUT nicht in Datei aus, wenn es von Cron ausgeführt wird

Das Skript bei einigen Pionts ruft eine systemeigene ausführbare Datei mit dem Aufruf von system() auf, die STDOUT einige Informationen liefert und STDERR - einige zehn bis einige hundert Zeilen über viele Minuten. Nachdem die ausführbare Datei fertig ist, fährt das Skript fort und protokolliert einige andere Informationen in der Protokolldatei.

Bis jetzt protokollierte das Skript nur seine eigene Ausgabe, ohne die native ausführbare Ausgabe, die ich in den gleichen Dateien anmelden möchte, wie sich das Perl-Skript anmeldet. Versuchte es mit folgenden zwei Methoden:

#!/usr/bin/perl 
#some other code 
@array_executable_and_parameters = qw/echo foo/ ; 
open $log_fh, '>>', 'log/logfile1.txt'; 
*STDOUT = $log_fh; 
*STDERR = $log_fh; 
print "log_fh=$log_fh\n"; 
system(@array_executable_and_parameters); 

$logfilename='log/logfile2.txt'; 
open(LOGFILEHANDLE, ">>$logfilename"); 
*STDOUT = LOGFILEHANDLE; 
*STDERR = LOGFILEHANDLE; 
print LOGFILEHANDLE "Somethinglogged\n"; 
system(@array_executable_and_parameters); 

Es funktioniert, wenn ich das Skript manuell ausführen, aber nicht, wenn sie von cron.

Ich weiß, es ist möglich, in der Crontab von Linux-Mitteln umleiten, aber dann muss ich den Dateinamen zu loggen wissen, die nur bekannt sein wird, wenn einige Daten ankommen, so scheint mir nicht machbar. Ich hätte auch gerne so viel wie möglich im Skript, ohne viele Abhängigkeiten von Linux usw. Ich habe auch keine Möglichkeit, irgendwelche zusätzlichen Module, Bibliotheken für Perl zu installieren, vorausgesetzt, es ist die einfachste Installation.

Wie bekomme ich STDOUT und STDERR aus dem Perl-Skript zu einer bestimmten Datei umgeleitet?

Und wenn möglich, wie erkenne ich den Dateinamen der STDOUT derzeit geht?

+0

Wie dies Perl-Skript aufgerufen, und wie genau rufen Sie 'system()'? – tripleee

+0

Von crontab: * * * * * /home/username/perl/myscript.pl Manuell: ./home/username/perl/myscript.pl Executable aus dem Inneren des Skript wie aufgerufen wird: System (@array_executable_and_parameters); – uldics

+0

Ihr interaktives Beispiel hat einen Punkt vor '/ home', also sind diese nicht äquivalent, es sei denn, Sie befinden sich im Stammverzeichnis; aber ich nehme an, das ist ein falsches Detail. Können Sie Ihre Frage mit einem einfachen 'system()' Aufruf im Demoskript bearbeiten, der nicht das tut, was Sie erwarten? – tripleee

Antwort

4

Die Neuzuweisung *STDOUT betrifft nur die Perl-interne Skalarbindung. Der richtige Weg, Standardausgabe auf der Systemebene zu umleiten ist so etwas wie

open (STDOUT, '>&', $log_fh) or die "$0: could not: $!"; 

Sie ähnlich Fehler von Ihrem anderen Systemaufrufe berichten sollte, die (und use strict und usw.) scheitern könnte.

cron läuft Ihre Arbeit in Ihrem Home-Verzeichnis, so dass, wenn der Pfad $HOME/log nicht vorhanden ist, nicht das Skript wird die Log-Datei-Handle öffnen (lautlos, da Sie nicht open Fehler protokollieren!)

+0

Was ist mit 'wählen'? – simbabque

+1

Habe das nicht speziell getestet, aber ja, TMTOWTDI. – tripleee

+3

@simbabque, 'select' beeinflusst auch' system' nicht. Nur 'open (STDOUT, '> &', $ log_fh)' und 'open (STDOUT, '>'," ... ") ändern fd 1 – ikegami

Verwandte Themen