我们在使用Linux服务器的时候,一般是使用终端利用SSH协议登录的。当你需要同时进行一些作业,但又不想打开多个终端的话就需要用到后台运行。
&
sh test.sh &
一些费时的作业可以这样放在后台运行,但需要注意的是后台运行的作业如果有输出,一样会输出到终端屏幕。有大量输出的情况下,最好将输出重定向至指定文件,比如这样:
sh test.sh > file.log 2>&1 &
关于重定向
Linux内核(kernel)利用文件描述符(file descriptor)来访问文件。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。常见的文件描述符是stdin、stdout和stderr。
系统预留文件描述符
- 0 —— stdin(标准输入)
- 1 —— stdout(标准输出)
- 2 —— stderr(标准错误)
重定向将输入文本通过截取模式保存到文件。>
表示的是覆盖写,如果需要追加写则用>>
。
所以回到上面那个列子:
sh test.sh > file.log 2>&1 &
> file.log
指的是标准输出重定向至file.log
文件,因为默认就是标准输出,所以这里的1 > file.log
中的1
可以省略。
2>&1
指的是标准错误重定向至标准输出的位置,即file.log
,因为标准输出已经被重定向至file.log
里了。
还有一种特殊的重定向方法:
sh test.sh > /dev/null
/dev/null
是一个特殊的设备文件,这个文件接受到任何数据都会被丢系,通常被称为位桶、黑洞。任何被重定向至这里的内容都会被丢弃。
nohup
不管是前台还是后台运行的作业,如果我们关闭终端窗口或者退出登录SSH甚至网络波动断开连接,作业就会被终止。这是因为系统信号SIGHUP
的缘故。
关于系统信号
登录Linux时,系统会分配给登录用户一个终端(Session)。
在这个终端运行的所有程序,包括前台进程组和后台进程组,一般都属于这个Session。
当用户退出Linux登录时,前台进程组和后台有对终端输出的进程将会收到SIGHUP信号。
这个信号的默认操作为终止进程,因此前台进程组和后台有终端输出的进程就会中止。
系统信号还有很多,这里不展开。
所以nohup
命令就登场了,它可以将程序以忽略挂起信号的方式运行起来,被运行的程序的输出信息将不会显示到终端。
nohup sh test.sh
这时输出不会显示在终端屏幕,而是自动追加到当前目录的nohup.out
文件,当然你也可以重定向至你想要的地方,这样就不会自动生成nohup.out
。
结合之前的&
后台命令,一般完整的用法就是这样:
nohup sh test.sh > file.log 2>&1 &
这时你就可以放心的退出SSH登录,让作业自动在服务器后台运行,之后回来查询日志文件就可以啦。