Linux provides a daemon function that enables the process to be executed out of the console, enabling the effect of background execution. However, after the process background execution, the original output data in the terminal console will not be visible.
So, how can we get the data back?
Over here. The theme of the article is about how to get the console data for the background process, and the principle should start with daemon.
Daemon mainly do two things:
1. Create a child process, exit the current process, and create a new session with a child process. This way, the child process will not be closed even if the parent process exits
2, the standard input. Standard output, standard error redirect/dev/null
The daemon implements roughly such as the following:
int daemonize (int nochdir, int noclose) {int fd;switch (fork ()) {Case-1:return ( -1); case 0:break;default:_exit (EXIT_SUCC ESS);} 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 St Din "); 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);}
So, to retrieve the console data of the process, just redirect the standard output, the standard error to the specified file, and then read the file.
code such as the following, saved as daemon_example.c
#include <signal.h> #include <unistd.h> #include <stdio.h> #include <fcntl.h>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);d up2 (FD, Stdout_fileno);d up2 (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);d up2 (FD, Stdout_fileno);d up2 (FD, Stderr_fileno); return;} int main () {signal (SIGUSR1, sigroutine); signal (SIGUSR2, Sigroutine);d Aemon (1,0); for (;;) {fprintf (stderr, "Test \ n");//continuously print testsleep (1);} return 0;}
Then, compile and execute this program: $ gcc-oDaemon_example Daemon_example. C$ chmod +x daemon_example $ ./Daemon_example
$ ps-ef| grep daemon_example
Root 11328 1 0 19:15?
00:00:00./daemon_example
As above, the process background was executed. Get PID 11328
Next, write a script to test this program, save as Test.sh:
#!/bin/bashpid=$1ps-p $pid >/dev/nullif [! $-eq 0]; Thenecho PID does not exist!exit 1fiecho pid $pidtrap "KILL-USR2 $pid && exit 1" HUP INT QUIT termkill-usr1 $pid echo It works,please wait. Sleep 1tail-f-N 0/tmp/console_temp.logecho done!
Execute this script with the results such as the following: $./test.sh 11328
PID 11328
It works,please wait.
Test
Testthen press CTRL + C to exit the script, where the script notifies the process to redirect standard output and standard errors to/dev/null. Continue execution in the background. In this way, this script becomes the debugging tool of the background process, need to execute the background data, do not need to shut down.
Of course, this is just a demo sample. The actual application should be improved. For example, the kill signal is changed to pipe or socket communication, the cache file size limit. or self-active clearance, etc.
article at the end. is not a bit trickery. Do you have any better way to welcome the comment exchange!
Reference: [1] Linux Gets the console data for the daemon process no flowering tree
Linux gets console data for background processes