Recently, many people have asked how to implement this method after they want to exit secureCRT and continue to run their own processes. I can say a lot about this method.
Why is there such a demand? As a system administrator, you often encounter this problem. When using telnet/ssh to log on to a remote Linux server, you need to run some time-consuming tasks, such as pinging some network segments in batches, sometimes the task fails or needs to be left out due to network instability. It will never end up. If you log out of SSH, then, your task will be terminated. Isn't it in vain? There are many ways to implement commands or tasks in the background, such as nohup, setsid, and screen.
After we log on to the server through SSH, generally, the operations or command input are all shell Sub-processes under sshd, such as opening an SSH terminal, enter ping www.163.com> output.txt & to view the process:
$ Ps-ef | grep ping
Sszheng 27491 27467 0 00:00:00 pts/0 ping www.163.com
Sszheng 27535 27467 0 00:00:00 pts/0 grep ping
Obviously, it is a sub-process of shell. The command is executed by a sub-shell in the background. The current shell (27467) gets control immediately and waits for user input, so my grep can be used. The background commands are executed in parallel with the current shell. They do not have mutual dependencies or waiting relationships, so they are asynchronous and parallel. Now the problem arises. If ssh exits and bash ends, what will happen to this process? Can the background execution continue?
There are two problems involved here: After we exit ssh, will we send a SIGHUP signal to our backend jobs when we exit the shell executed?
If the SIGHUP signal is sent, all processes running in the shell will be terminated, that is, the desired background execution is not implemented. In shell options, the huponexit option indicates whether to send the SIGHUP signal when the shell is exited?
$ Shopt
Cdable_vars off
Cdspell off
Checkhash off
Checkwinsize off
Cmdhist on
Dotglob off
Execfail off
Expand_aliases on
Extdebug off
Extglob off
Extquote on
Failglob off
Force_fignore on
Gnu_errfmt off
Histappend off
Histreedit off
Histverify off
Hostcomplete on
Huponexit off
Interactive_comments on
Lithist off
Login_shell on
Mailwarn off
No_empty_completion off
Nocaseglob off
Nocasematch off
Nullglob off
Progcomp on
Promptvars on
Restricted_shell off
Shift_verbose off
Sourcepath on
Xpg_echo off
In the above default options, huponexit off. In this case, when you exit the shell, the background program will continue to run, but this is a global option, sometimes we often want to exit the shell, and the process initiated by the shell ends, instead of running it all the time, because sometimes you may have opened many sub-processes and don't have time to close them one by one, right ?? This option is usually recommended.
After huponexit is enabled, the jobs in the background will exit after shell exits. However, we can perform separate operations on specific tasks, you can use the following centralized method.
1. nohup
The purpose of nohup is to let the submitted command ignore The hangup signal. Usage:
$ Nohup ping www.163.com &
If there is no redirected input or output, the standard output and standard errors are redirected to the nohup. out file by default. In general, add "&" to run the command in the background, and use "> filename 2> & 1" to change the default redirection file name. After exiting the shell, ping continues until the command execution ends.
$ Ps-ef | grep ping
Sszheng 5377 5311 0 00:00:00 pts/1 ping www.163.com
Sszheng 5379 5311 0 00:00:00 pts/1 grep ping
After exiting shell, log on to the system again and check that the ping process is still running, but the PPID is changed to 1, which is the orphan process managed by init. Let's talk about the orphan process later.
$ Ps-ef | grep ping
Sszheng 5377 1 0 16: 51? 00:00:00 ping www.163.com
Sszheng 5389 5383 0 00:00:00 pts/0 grep ping
2. setsid
Nohup is a shell sub-process that ignores the HUP signal to prevent the process from being interrupted in the middle. You can also use another method. The process is not a shell sub-process of the terminal that accepts the HUP signal, naturally, it will not be affected by the HUP signal. It's really a white cat and a black cat. It's a good cat to catch a mouse.
Shell provides the setsid method,
$ Setsid ping www.163.com &> 163.txt
$ Ps-ef | grep ping
Sszheng 5377 1 0 16: 51? 00:00:00 ping www.163.com
Sszheng 5395 1 0 16: 56? 00:00:00 ping www.163.com
Sszheng 5397 5383 0 00:00:00 pts/0 grep ping
In the previous example, the ping parent process is 5311. When its parent process exits, It is adopted by init (PID = 1, however, if setsid directly sends ping (pid = 5395) to init, the shell exit will not matter.
3 ,(&)
For more information about subshell usage, we know that including one or more names in "()" allows these commands to run in the sub-shell, when we put "&" into "()", we will find that the submitted jobs are not in the job list, that is, they cannot be viewed through jobs. Take a look at the process id below and you will know:
$ (Ping www.163.com &)
$ Ps-ef | grep ping
Sszheng 5377 1 0 16: 51? 00:00:00 ping www.163.com
Sszheng 5395 1 0 16: 56? 00:00:00 ping www.163.com
Sszheng 5401 1 0 00:00:00 pts/0 ping www.163.com
Sszheng 5403 5383 0 00:00:00 pts/0 grep ping
As you can see, the parent process of the execution of 5401 is init, so that the hup signal can be ignored.
Speaking of this, I believe everyone understands the background execution method. Simply put, after the bash process is terminated, the init process will take over the "orphan processes" left by the parent process ", therefore, PPID is 1, while orphan processes are not zombie processes. The following are their concepts and differences:
Zombie Process: A child process exits when its parent process does not call wait () or waitpid. This sub-process is a zombie process.
Orphan process: if a parent process exits and one or more child processes are still running, those child processes will become orphan processes. The orphan process will be adopted by the init process (process number 1) and collected by the init process.
Briefly speaking, screen is also an important tool for background execution, but its functions are far more than background execution.
Screen is a window manager that can reuse a physical terminal among multiple processes. Screen has the concept of session. You can create multiple screen Windows in one screen session, just like operating a real telnet/SSH connection window in each screen window. There are several ways to create a new window in screen:
1. Directly type the screen command in the command line.
$ Screen
Screen creates a full Screen window for executing shell. You can execute any shell program, as in the ssh window. In this window, type exit to exit the window. If this is the only window of the screen Session, the screen session will exit; otherwise, the screen will automatically switch to the previous window.
2. The Screen command is followed by the program you want to execute.
$ Screen vi test. sh
Screen creates a single window session for executing vi test. sh. exiting vi will exit this window/session.
3. Create a screen session in both of the preceding methods. We can also create a new window in an existing screen session. In the current screen window, type C-a c, that is, Ctrl + a, and then press c. screen generates a new window in the session and switches to the window.
The specific usage will not be mentioned. Since it does not belong to ssh management, why should we accept the exit signal? Pay attention to the concept of session.
If you are interested in shoes, you can also look at the related things of disown. The requirement of this kind is: if you add nohup or setsid before the command, you can avoid the influence of the HUP signal. But if we have submitted the command without any processing, how can we remedy it to avoid the impact of the HUP signal?
We can achieve our goal in the following ways.
Use disown-h jobspec to make a Job ignore the HUP signal.
Use disown-ah to make all jobs ignore the HUP signal.
Use disown-rh to ignore the HUP signal for running jobs.
The object in the above method is a job. If we add "&" at the end of the command to make it a job and run it in the background, we can use the jobs command to get a list of all jobs. But if the current command is not run as a job, how can I get its job number? The answer is to press CTRL-z (hold down the Ctrl key while holding down the z key!
CTRL-z is used to Suspend the current process (Suspend), then we can use the jobs command to query its job number, and then use bg jobspec to put it in the background and continue running. It should be noted that if the suspension will affect the running results of the current process, we do not recommend that you use it.
Let's talk about this. It's wrong. Please give me some advice.
Teddy. xiong MAIL: cug@live.cn