2017-02-20 2 views
1

서비스 (예 : 데몬)로 Perl 스크립트를 실행해야합니다. 나는 아래의 C 프로그램을 찾았고 일반적으로 잘 작동한다. 그러나 perl 스크립트가 예외로 인해 죽는 경우 오류 메시지가 표시되지 않습니다. 펄에서 오류를 어떻게 얻을 수 있습니까?STDERR from service from syslog

터미널 (즉, STDERR)을 사용할 수 없으므로 최선의 방법은 syslog에 오류 메시지가 표시되는 것입니다. 나는 누군가가 코드를 일부 "사용 준비"를 제공 할 수 있다면 C.에 대한 단서가 좋은 없을 것 갖고 있기 때문에

#include <sys/types.h> 
#include <sys/stat.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <unistd.h> 
#include <syslog.h> 
#include <string.h> 
#include <signal.h> 
#include <syslog.h> 


int main(int argc, char *argv[]) {  
    pid_t pid, sid;  

    if(argc < 1) { 
     printf("At least one argument expected.\n"); 
     return EXIT_FAILURE; 
    } 

    char arg[1000]; 
    strcpy(arg, argv[1]); 
    int i = 2; 
    for(i = 2; i < argc; i++) { 
     strcat(arg, " "); 
     strcat(arg, argv[i]);  
    } 

    /* Fork off the parent process */ 
    pid = fork(); 
    if (pid < 0) { 
     exit(EXIT_FAILURE); 
    } 

    /* If we got a good PID, then we can exit the parent process. */ 
    if (pid > 0) { 
     exit(EXIT_SUCCESS); 
    } 

    /* Open a connection to the syslog server */ 
    openlog ("mediationd", LOG_PID, LOG_DAEMON); 
    syslog(LOG_NOTICE, "Successfully started daemon\n"); 

    /* Try to create our own process group */ 
    sid = setsid(); 
    if (sid < 0) { 
     syslog(LOG_ERR, "Could not create process group\n"); 
     closelog(); 
     exit(EXIT_FAILURE); 
    } 

    /* Catch, ignore and handle signals */ 
    signal(SIGCHLD, SIG_IGN); 
    signal(SIGHUP, SIG_IGN); 

    /* Fork off for the second time*/ 
    pid = fork(); 

    /* An error occurred */ 
    if (pid < 0) { 
     syslog(LOG_ERR, "Could not fork second time\n"); 
     closelog(); 
     exit(EXIT_FAILURE); 
    } 

    /* Success: Let the parent terminate */ 
    if (pid > 0) { 
     exit(EXIT_SUCCESS); 
    } 

    /* Change the file mode mask */ 
    umask(0);  

    /* Change the current working directory */ 
    if ((chdir("/")) < 0) { 
     syslog(LOG_ERR, "Could not change working directory to /\n"); 
     exit(EXIT_FAILURE); 
    } 

    /* Close the standard file descriptors */ 
    close(STDIN_FILENO); 
    close(STDOUT_FILENO); 
    close(STDERR_FILENO); 

    /* Starting the perl script which does the job. 
    * Note, this perl scripts runs forever till it is terminated by 'kill' command */ 
    system(arg); 

    /* Terminate the daemon */ 
    syslog (LOG_NOTICE, "Daemon terminated."); 
    closelog(); 
    return EXIT_SUCCESS; 
} 

나는, 간단한 복사/붙여 넣기하여이 작은 프로그램을 썼습니다. 아래 그림과 같이

업데이트

나는 내 코드를 업데이트했습니다. 그것은 잘 작동하는 것, 그러나 나는 무엇인가 놓치거나 나는 다른 것을 추가해야합니까? 네이티브 펄에서 그것을하고 싶은 경우

/* Close the standard file descriptors */ 
close(STDIN_FILENO); 
close(STDOUT_FILENO); 

/* Redirect STDERR to syslog, i.e. logger */ 
FILE *fl; 
fl = popen("logger --id --priority user.error", "w"); 
if (fl == NULL) { 
    syslog(LOG_ERR, "Could not open 'looger'\n"); 
    exit(EXIT_FAILURE); 
} 
int nf = fileno(fl); 
dup2(nf, STDERR_FILENO); 

/* Starting the perl script which does the job. 
* Note, this perl scripts runs forever till it is terminated by 'kill' command */ 
system(arg); 
close(STDERR_FILENO); 

/* Terminate the daemon */ 
syslog (LOG_NOTICE, "Daemon terminated\n"); 
closelog(); 
return EXIT_SUCCESS; 
+0

execvp() 또는 비슷한 호출을 할 때 stdin/stdout/stderr를 파일로 리디렉션하는 방법은 무엇입니까?] (http://stackoverflow.com/questions/14543443/in-c-how- do-you-redirect-stdin-stdout-stderr-to-files-when-execvp-making) 또는 – Toby

+0

@Toby 그건 아주 좋은 복제품이 아닙니다. syslog를 통한 로깅은 파일에 직접 기록하는 것을 포함하지 않습니다. – Kenster

+0

12k 담당자가 있으면 코딩 서비스가 아님을 알아야합니다. 그리고 왜이 perl ** 및 ** C 태그가 붙어 있습니까? Perl 버전을 작성하려고한다면 C 코드는 쓸모가 없습니다. C 코드를 수정하고 Perl을 언급하는 이유는 무엇입니까? – Olaf

답변

1

이 나를 위해 작동합니다 : 펄이 die() 또는 유사한과 충돌하는 경우

use IO::Handle; 
open(SYSLOG, "| /usr/bin/logger -t hello") or die("syslog problem $!"); 
*STDERR = *SYSLOG; 
autoflush STDERR 1; 

, 로그 메시지를 볼 수 있습니다.