使用AWS Boto3 EC2 send_command运行Python脚本几小时后意外终止
使用AWS Boto3的send_command()函数在约100台EC2实例上长时间(数天)运行本地Python脚本,相关代码如下:
ssm_client = boto3.client('ssm', region_name = 'eu-west-1') commands_to_execute = """cd /home/ubuntu set -x exec 3>&1 4>&2 trap 'exec 2>&4 1>&3' 0 1 2 3 exec 1>logv5.out 2>&1 python3 myscript.py""" command_lines_to_execute = commands_to_execute.split('\n') ssm_client.send_command(InstanceIds=[instance_id], DocumentName="AWS-RunShellScript", Parameters={'commands': commands_to_execute})
日志重定向代码如下,功能正常,但运行约一小时后,每个EC2实例中的Python进程无任何输出直接终止:
set -x exec 3>&1 4>&2 trap 'exec 2>&4 1>&3' 0 1 2 3 exec 1>logv5.out 2>&1
曾尝试通过screen启动命令避免虚拟bash会话终止导致进程结束,但问题仍未解决。
核心原因
SSM Run Command会话超时限制
AWS SSM的AWS-RunShellScript文档默认会话超时时间为3600秒(1小时),超时后SSM Agent会终止整个bash会话及所有子进程——哪怕用screen,只要是该会话启动的进程,都会被SSM Agent清理。进程组关联问题
Python脚本作为bash的子进程,属于同一个进程组。当SSM终止bash会话时,会向整个进程组发送SIGHUP信号,导致所有关联进程(包括screen内的进程)被终止。IO空闲检测
SSM Agent会监控会话的标准输入/输出状态,如果Python脚本长时间没有输出到SSM关联的IO流(即使你重定向到了本地文件),Agent可能判定会话已闲置,主动终止进程。
解决办法
1. 让进程脱离SSM会话进程组
使用nohup和disown组合,让Python进程彻底脱离bash会话的控制,即使SSM终止bash,进程仍能持续运行:
cd /home/ubuntu nohup python3 myscript.py > logv5.out 2>&1 & disown
nohup:忽略SIGHUP信号,将进程与终端会话分离&:后台运行进程disown:将进程从bash的作业列表中移除,避免bash退出时发送信号
2. 调整SSM会话超时时间
在send_command时显式设置TimeoutSeconds参数,延长会话超时时间(最大支持12小时,即43200秒):
ssm_client.send_command( InstanceIds=[instance_id], DocumentName="AWS-RunShellScript", Parameters={'commands': commands_to_execute}, TimeoutSeconds=43200 # 设置为12小时 )
注意:此方法仅延长会话存活时间,若需数天运行,仍需结合nohup/disown或进程管理器。
3. 使用systemd托管进程(推荐长期运行场景)
将Python脚本注册为systemd服务,由systemd负责进程的启动、监控和重启,彻底脱离SSM会话依赖:
通过SSM执行以下命令:
# 创建systemd服务文件 cat > /etc/systemd/system/myscript.service << EOF [Unit] Description=Long-running Python Script Service [Service] User=ubuntu WorkingDirectory=/home/ubuntu ExecStart=/usr/bin/python3 myscript.py StandardOutput=append:/home/ubuntu/logv5.out StandardError=append:/home/ubuntu/logv5.out Restart=always # 进程意外终止时自动重启 [Install] WantedBy=multi-user.target EOF # 重载systemd配置并启动服务 systemctl daemon-reload systemctl start myscript.service
此方法不仅能避免SSM会话影响,还能提供进程监控、自动重启等能力,适合长期运行的任务。
4. 排查脚本自身问题
若以上方法仍未解决,需检查Python脚本是否存在隐性错误:
- 在脚本中添加全局异常捕获,将异常信息写入日志
- 监控实例的内存、CPU使用情况,排查内存泄漏或资源耗尽问题
内容的提问来源于stack exchange,提问作者meliksahturker

