一个echo引起的进程崩溃-阿里云开发者社区

开发者社区> exinnet> 正文

一个echo引起的进程崩溃

简介:
+关注继续查看
最近在编写后台程序时遇到一个问题。发现后台程序总是莫名其妙的die掉。经排查,发现罪魁祸首是一个echo。
案情重现:
1.ssh登陆服务器

2.新建一个php文件test.php,代码如下:


<?php
sleep(50);
echo "aaa\n";
file_put_contents("/tmp/test.txt",time());
?>

3.用以下命令执行test.php程序
$ php test.php &
查看 /tmp/test.txt 文件的内容为 1381325659
4.然后再次执行如下命令。命令执行后,马上使用exit命令退出登陆
$ php test.php &
5.然后ssh登陆服务器,发现/tmp/test.txt 文件的内容依然是 1381325659。说明第二次执行test.php时,file_put_contents函数没有执行,或者没有执行成功。

追查真凶
为什么第二次执行的时候file_put_contents函数没有执行,或者没有执行成功?
让我们使用万能的strace命令查看下程序执行过程中,系统调用情况。
正常情况下,strace结果中会有如下显示:
nanosleep({50, 0}, {50, 0}) = 0
write(1, "aaa\n", 4aaa
) = 4
lstat("/tmp/test.txt", {st_mode=S_IFREG|0644, st_size=10, ...}) = 0
lstat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=1576960, ...}) = 0
open("/tmp/test.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
lseek(3, 0, SEEK_CUR) = 0
write(3, "1381326235", 10) = 10
close(3) = 0
close(2) = 0
close(1) = 0
munmap(0x2b4dd1414000, 4096) = 0
close(0) = 0

如果退出ssh后,再登陆,strace结果中会有如下显示:
write(1, "aaa\n", 4) = -1 EIO (Input/output error)
close(2) = 0
close(1)
munmap(0x2b4412622000, 4096) = 0
close(0) = 0

注意两次strace的结果蓝色部分。根据strace结果,可以肯定是因为echo时产生了EIO错误导致进程终止,最终没有执行file_put_contents函数。

一追到底
为什么退出登陆后,再登陆,就会发生EIO错误呢?这个和linux的会话处理有关。
当用户ssh登陆一个服务器时,也就开始了一个会话。会话开始后,标准输入(stdin)、标准输出(stdout)、标准错误(stderr)会连接到一个对应的终端(pty)。

用户登陆后,任何标准输出都会在终端中有反应。标准输出的文件句柄是1。因此,php中的echo("aaa\n") 会导致执行系统调用write(1, "aaa\n", 4). 会在终端中写aaa\n。

​当用户退出登陆时,一个会话就结束了。会话结束时,修改所有打开该终端的文件句柄,改成不可读也不可写;

​用户退出登陆后再执行write(1, "aaa\n", 4),会报EIO错误。因为终端句柄已经不可写。EIO错误发生后,导致进程结束。

解决办法
方法一:
​使用重定向符号&把标准输出重定向到空洞。
$ php test.php > /dev/null 2 >&1 &
方法二:
使用nohup。[推荐使用此方法]
$ nohup php test.php &


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4617 0
WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口)
原文 WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口) WPF 的 UI 逻辑只在同一个线程中,这是学习 WPF 开发中大家几乎都会学习到的经验。如果希望做不同线程的 UI,大家也会想到使用另一个窗口来实现,让每个窗口拥有自己的 UI 线程。
1898 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
10784 0
阿里云服务器远程登录用户名和密码的查询方法
阿里云服务器远程连接登录用户名和密码在哪查看?阿里云服务器默认密码是什么?云服务器系统不同默认用户名不同
846 0
LINUX C 父进程建立多个子进程循环非堵塞回收列子
下面 代码主要用于复习,留于此 点击(此处)折叠或打开 /*************************************************************************   > File Name: fork5.
816 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
3664 0
+关注
exinnet
淘宝技术专家
91
文章
70
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载