You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在PHP的shell_exec中正确嵌入Shell命令以覆盖远程文件?

解决PHP中shell_exec执行SSH覆盖远程文件失败的问题

我来帮你梳理下可能的原因和对应的解决办法,毕竟bash里正常但PHP里不行,大概率是运行环境或者命令处理的差异导致的:

1. PHP运行用户的SSH权限问题

咱们在本地bash里用的是自己的用户,密钥存在这个用户的~/.ssh目录里,但PHP通常是用www-data(Apache)或者nginx这类系统用户运行的,这些用户可能根本没有访问你个人密钥的权限,甚至连自己的.ssh目录都没有。

解决办法:

  • 给PHP运行用户配置独立的SSH密钥对,把公钥添加到远程服务器的root/.ssh/authorized_keys
  • 或者把你的私钥复制到PHP用户的.ssh目录下,记得设置正确的权限:
    sudo mkdir /var/www/.ssh
    sudo cp ~/.ssh/id_rsa /var/www/.ssh/
    sudo chown -R www-data:www-data /var/www/.ssh
    sudo chmod 700 /var/www/.ssh
    sudo chmod 600 /var/www/.ssh/id_rsa
    

2. 变量未转义导致命令被破坏

你直接把$_GET["phone"]放到shell命令里,如果手机号里包含特殊字符(比如空格、&|这类),会直接打乱命令结构,甚至引发安全问题。

解决办法:用escapeshellarg()对变量进行转义,确保它作为一个完整的参数传入shell:

$number = $_GET["phone"];
$safe_number = escapeshellarg($number); // 转义特殊字符

3. SSH命令未明确指定密钥路径

PHP的运行环境可能没有正确的环境变量,导致SSH找不到密钥文件。这时候可以在SSH命令里直接指定私钥路径,避免依赖环境变量:

$out = shell_exec("echo $safe_number | ssh -i /var/www/.ssh/id_rsa root@0.0.0.0 'cat > /path/to/file/number.txt'");

4. 开启错误调试,定位具体问题

shell_exec默认只返回标准输出,错误信息会被忽略,咱们可以把标准错误重定向到标准输出,这样就能看到具体的报错了:

$out = shell_exec("echo $safe_number | ssh -i /var/www/.ssh/id_rsa root@0.0.0.0 'cat > /path/to/file/number.txt' 2>&1");
var_dump($out); // 打印所有输出,包括错误

修改后的完整代码示例

$number = $_GET["phone"];
$safe_number = escapeshellarg($number);
// 替换成你实际的密钥路径和远程地址
$out = shell_exec("echo $safe_number | ssh -i /var/www/.ssh/id_rsa root@0.0.0.0 'cat > /path/to/file/number.txt' 2>&1");
var_dump($out);

内容的提问来源于stack exchange,提问作者Piyumi Guruge

火山引擎 最新活动