企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### 测试代码如下 ```php <?php $a = 1; while(true){ echo "Tinywan ".$a++.'\r\n'; sleep(1); } ``` > 是一个输出`Tinywan`字符串与循环轮数的死循环程序,每输出一行就休眠1秒。 ### 原始输出 前台执行该程序运行效果 ```shell www@manager1:~/build$ php tinywan.php Tinywan : 1 Tinywan : 2 Tinywan : 3 Tinywan : 4 Tinywan : 5 Tinywan : 6 Tinywan : 7 Tinywan : 8 Tinywan : 9 ^C ``` 程序每隔一秒会在终端输出一个字符串 。 此时如果键入`Ctrl+C` ,程序会收到一个`SIGINT`信号,如果不做特殊处理,程序的默认行为是终止(如上图)。 > **信号量`SIGINT `** > > 程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。 ### 使用 `&` 下来使用 `php tinywan.phpt & `后台运行程序,会是什么效果呢? ```php www@manager1:~/build$ php tinywan.php & [1] 17153 www@manager1:~/build$ Tinywan : 1 Tinywan : 2 Tinywan : 3 ^C www@manager1:~/build$ Tinywan : 8 Tinywan : 9 Tinywan : 10 ^C www@manager1:~/build$ Tinywan : 11 Tinywan : 12 ^C www@manager1:~/build$ Tinywan : 16 ``` 如上运行结果: * 首先会在终端显示进程号是`17153` * 键入**Ctrl + C**,发出SIGINT信号,程序会继续运行 。 ps确认一下,确认进程依然在运行,进程号是`17153`。 ```shell www@manager1:~$ ps -axu|grep php www 17153 0.0 1.2 210596 25788 pts/2 S 09:02 0:00 php tinywan.php www 17386 0.0 0.0 14428 996 pts/3 S+ 09:07 0:00 grep --color=auto php ``` 此时如果关掉session(关闭当前的终端回话窗口),程序会收到一个SIGHUP信号,此时会怎么样呢? ```shell www@manager1:~$ ps -axu|grep php www 17386 0.0 0.0 14428 996 pts/3 S+ 09:07 0:00 grep --color=auto php ``` ps再次确认,可以看到关闭session之后,进程号是`17153`的进程也关闭了。 > 如果不关闭终端的情况,想结束该进程,可以使用kill命令:`kill -9 17153` ### 使用 nohup ```shell www@manager1:~/build$ nohup php tinywan.php nohup: ignoring input and appending output to 'nohup.out' ``` 使用nohup 运行程序`tinywan.php`,会发现: * 前台没有出现进程号 * 有一个`“忽略输入,输出至nohup.out”`的提示 * Tinywan的输出也没有出现在前台 ```shell www@manager1:~$ ps -aux |grep php www 17557 0.0 1.2 210596 25636 pts/3 S+ 09:12 0:00 php tinywan.php www 17689 0.0 0.0 14428 1036 pts/2 S+ 09:15 0:00 grep --color=auto php ``` > 忽略输入并将输出附加到'nohup.out',查看这个文件内容 手动ps看进程号,这次 tinywan.php 的进程号是 `17557`。 此时如果关掉session,程序会收到一个`SIGHUP`信号,程序会不会关闭呢? > **信号量 `SIGHUP `** > > 本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业,这时它们与控制终端不再关联。 > > 登录Linux时,系统会分配给登录用户一个终端(Session)。在这个终端运行的所有程序,包括前台进程组和后台进程组,一般都属于这个 Session。当用户退出Linux登录时,前台进程组和后台有对终端输出的进程将会收到SIGHUP信号。这个信号的默认操作为终止进程,因此前台进 程组和后台有终端输出的进程就会中止。不过可以捕获这个信号,比如wget能捕获SIGHUP信号,并忽略它,这样就算退出了Linux登录,wget也能继续下载。 > > 此外,对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件。 ```shell www@manager1:~$ ps -aux |grep php www 17557 0.0 1.2 210596 25636 ? S 09:12 0:00 php tinywan.php www 17725 0.0 0.0 14428 1028 pts/2 S+ 09:16 0:00 grep --color=auto php www@manager1:~$ ps -aux |grep php www 17557 0.0 1.2 210596 25636 ? S 09:12 0:00 php tinywan.php www 17734 0.0 0.0 14428 1092 pts/2 S+ 09:16 0:00 grep --color=auto php ``` 关掉session后,再次ps看一下,ID为`17557`的 tinywan.php 进程还在。 > 这些只能通过kill把程序干掉了,killall之后,ps查看进程已经关闭。 ### nohup 和 & 同时使用 终端运行 ```shell www@manager1:~/build$ nohup php tinywan.php & [1] 17947 www@manager1:~/build$ nohup: ignoring input and appending output to 'nohup.out' ^C www@manager1:~/build$ ``` 使用`nohup php tinywan.php &`运行程序后,可以看到 * 会在终端显示进程号是 17947 * 也会有一个“忽略输入,输出至nohup.out”的提示 * 键入Ctrl + C,发送SIGINT信号,似乎没反应。 关闭session,发送SIGHUP信号,再来看看。 ```shell www@manager1:~/build$ ps -aux |grep php www 17947 0.0 1.2 210596 25644 pts/2 S 09:22 0:00 php tinywan.php www 18013 0.0 0.0 14428 1092 pts/2 S+ 09:24 0:00 grep --color=auto php ``` ID为`17947`的进程依然存在,后续也只能用kill来关闭它。 ### 结论 使用`&`后台运行程序: - 结果会输出到终端 - 使用Ctrl + C发送SIGINT信号,程序免疫 - 关闭session发送SIGHUP信号,程序关闭 使用`nohup`运行程序: - 结果默认会输出到nohup.out - 使用Ctrl + C发送SIGINT信号,程序关闭 - 关闭session发送SIGHUP信号,程序免疫 > **平日线上经常使用`nohup`和`&`配合来启动程序** - 同时免疫SIGINT和SIGHUP信号 - (最佳实践)不要将信息输出到终端标准输出,标准错误输出,而要用日志组件将信息记录到日志里