Мне нужно запустить скрипт Perl в качестве службы (например, daemon). Я нашел программу C ниже и вообще работает нормально. Однако, если скрипты perl умирают с исключением, я не получаю никакого сообщения об ошибке. Как я могу получить ошибку от perl?Перенаправить STDERR из службы в syslog
Терминал (т. Е. STDERR) недоступен, я предполагаю, что наилучшей идеей было бы получить сообщения об ошибках в syslog
.
#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;
}
Я написал эту крошечную программу простым копировать/вставить, так как у меня нет понятия о С. Не было бы хорошо, если кто-то может предоставить некоторые «готовые к использованию» код.
Update
Я обновил свой код, как показано ниже. Кажется, что он работает хорошо, но я ничего не пропускаю или должен добавить что-то еще?
/* 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;
Возможный дубликат [In C как вы перенаправляете stdin/stdout/stderr в файлы при выполнении execvp() или аналогичного вызова?] (Http://stackoverflow.com/questions/14543443/in-c-how- do-you-redirect-stdin-stdout-stderr-to-files-when-making-an-execvp-or) – Toby
@Toby Это не очень хороший дубликат. Вход в систему syslog не предусматривает прямой записи в файл. – Kenster
С 12k повторениями вы должны знать, что мы не являемся кодовым сервисом. И почему этот помеченный perl ** и ** C? Если вы намереваетесь написать Perl-версию, C бесполезен, если вы хотите, чтобы C-код был исправлен, почему даже упоминать Perl? – Olaf