Windows本地Subprocess运行正常,Linux服务器运行时进程挂起求助
解决Linux下subprocess调用PHP脚本挂起的问题
看起来你遇到的是跨平台subprocess调用的典型问题,我来帮你一步步排查:
1. 先修正shell=True的参数传递逻辑
在Linux环境下,shell=True的参数处理和Windows完全不一样。你当前的写法:
p = subprocess.Popen(["php", "random.php", username, password], stdout=subprocess.PIPE, shell=True)
会触发系统执行/bin/sh -c php random.php username password——shell会把php当成要执行的命令,后面的random.php、用户名密码全变成了shell自身的参数,根本没传递给PHP脚本!这会导致PHP进入交互模式一直等待输入,自然就挂起了。
解决方法有两种:
- 把命令整合成单个字符串(推荐这种,shell=True时字符串形式更直观):
cmd = f"php random.php {username} {password}" p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) - 或者保持列表形式,但要把完整命令作为
sh -c的参数内容:
注意:如果用户名/密码包含空格、引号等特殊字符,要先做转义处理,避免命令注入或者参数解析错误。p = subprocess.Popen( ["sh", "-c", f"php random.php {username} {password}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE )
2. 处理stderr缓冲区,避免阻塞
你之前只捕获了stdout,但如果PHP脚本有错误输出(比如警告、Notice信息),这些内容会存在stderr缓冲区里。当缓冲区被占满时,进程会被强制阻塞,等待读取stderr。所以一定要同时捕获标准错误流:
cmd = f"php random.php {username} {password}" p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) stdout, stderr = p.communicate() # 转成可读字符串打印 print("脚本输出:", stdout.decode('utf-8')) print("错误信息:", stderr.decode('utf-8'))
这样既能避免缓冲区满导致的挂起,还能看到脚本的错误提示,方便排查问题。
3. 检查路径与权限问题
- 确认PHP命令的绝对路径:Linux上部分环境的用户PATH可能不包含PHP路径,你可以在服务器上执行
which php拿到绝对路径(比如/usr/bin/php),替换脚本里的php。 - 确认脚本路径:如果
random.php不在Python脚本的当前工作目录,一定要用绝对路径(比如/home/sam/scripts/random.php),避免PHP找不到脚本而进入交互模式。 - 检查脚本权限:确保服务器上的运行用户有读取
random.php的权限,可执行chmod 644 random.php赋予读权限。
4. 先在命令行验证脚本可用性
先跳过Python,直接在Linux服务器的终端执行:
php random.php 你的测试用户名 你的测试密码
看看脚本能不能正常运行、有没有输出或错误提示。如果命令行都跑不通,那问题出在PHP脚本或环境配置上,和Python的subprocess无关。
按照上面的步骤一步步排查,应该能解决你的挂起问题~
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

