2、將標准輸入,標准輸出,標准錯誤都重定向/dev/null
daemon 實現大致如下:
int daemonize(int nochdir, int noclose) { int fd; switch (fork()) { case -1: return (-1); case 0: break; default: _exit(EXIT_SUCCESS); } if (setsid() == -1) return (-1); if (nochdir == 0) { if(chdir("/") != 0) { perror("chdir"); return (-1); } } if (noclose == 0 && (fd = open("/dev/null", O_RDWR, 0)) != -1) { if(dup2(fd, STDIN_FILENO) < 0) { perror("dup2 stdin"); return (-1); } if(dup2(fd, STDOUT_FILENO) < 0) { perror("dup2 stdout"); return (-1); } if(dup2(fd, STDERR_FILENO) < 0) { perror("dup2 stderr"); return (-1); } if (fd > STDERR_FILENO) { if(close(fd) < 0) { perror("close"); return (-1); } } } return (0); }所以,想取回進程的控制台數據,只要將標准輸出,標准錯誤重定向到指定文件,然後讀取這個文件就好了。 文章這裡寫了個例子,簡單演示下(這裡通過kill信號完成進程通信,有點粗暴) 代碼如下,保存為 daemon_example.c
#include然後,編譯和執行這個程序: $ gcc -o daemon_example daemon_example.c $ chmod +x daemon_example $ ./daemon_example#include #include #include static int fd = -1; void sigroutine(int dunno) { switch (dunno) { case SIGUSR1: fprintf(stderr, "Get a signal -- SIGUSR1 \n"); if (fd != -1) close(fd); fd = open("/tmp/console_temp.log", O_RDWR|O_APPEND|O_CREAT, 0600); if (fd == -1) break; dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); break; case SIGUSR2: fprintf(stderr, "Get a signal -- SIGUSR2 \n"); if (fd != -1) close(fd); fd = open("/dev/null", O_RDWR, 0); if (fd == -1) break; dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); break; } return; } int main() { signal(SIGUSR1, sigroutine); signal(SIGUSR2, sigroutine); daemon(1,0); for (;;){ fprintf(stderr,"test \n") ; // 不斷打印test sleep(1); } return 0; }
#!/bin/bash pid=$1 ps -p $pid>/dev/null if [ ! $? -eq 0 ] ; then echo pid does not exist! exit 1 fi echo pid $pid trap "kill -usr2 $pid && exit 1" HUP INT QUIT TERM kill -usr1 $pid echo it works,please wait.. sleep 1 tail -f -n 0 /tmp/console_temp.log echo done!執行這個腳本,結果如下: $ ./test.sh 11328