You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP向Bash脚本传递变量失败问题求助

排查PHP到Bash脚本的变量传递问题

我来帮你梳理下这个问题的核心原因,其实主要是参数顺序不匹配加上权限和安全处理的小问题,咱们一步步解决:

1. 最关键的问题:Bash脚本参数顺序完全颠倒了

你在PHP里传递的参数顺序是:$USERNAME $PASSWORD $NEWPASS,也就是Bash脚本的$1是用户名,$2是原密码,$3是新密码。但你的Bash脚本里写的是:

PASSWORD=$1 NEWPASS=$2 USERNAME=$3

这直接把三个变量的对应关系搞反了!脚本拿到的完全是错误的参数,自然没法正常执行。

2. 额外的坑:sudo权限与原密码验证

  • 默认web服务器用户(比如www-data)没有sudo执行脚本的权限,需要配置免密sudo;
  • root用户执行passwd时不需要验证原密码,这会导致任何知道用户名的人都能改密码,非常不安全,得先验证原密码的正确性。

修正后的代码与配置

修正后的Bash脚本(chngpass.sh)

#!/bin/bash
# 修正参数顺序:$1=用户名,$2=原密码,$3=新密码
USERNAME="$1"
OLD_PASSWORD="$2"
NEW_PASSWORD="$3"

# 先验证原密码是否正确(用su模拟用户登录验证)
echo "$OLD_PASSWORD" | su - "$USERNAME" -c "echo '原密码验证通过'" 2>/dev/null
if [ $? -ne 0 ]; then
    echo "ERROR: 原密码不正确"
    exit 1
fi

# 用--stdin传递新密码,避免交互问题
echo -e "$NEW_PASSWORD\n$NEW_PASSWORD" | passwd --stdin "$USERNAME"
if [ $? -eq 0 ]; then
    echo "SUCCESS: 密码修改成功"
else
    echo "ERROR: 密码修改失败"
    exit 1
fi

修正后的PHP代码

<html>
<title> New VPN password</title>
<h1> Your New VPN login details are</h1>
</html>
<?php
// 用空合并运算符处理POST参数,避免未定义索引警告
$USERNAME = $_POST['USERNAME'] ?? '';
$PASSWORD = $_POST['PASSWORD'] ?? '';
$NEWPASS = $_POST['NEWPASS'] ?? '';

// 检查所有字段是否填写
if(empty($USERNAME) || empty($PASSWORD) || empty($NEWPASS)) {
    echo "<h2>You must fill in all fields</h2>";
    die ("Click Back to start again.");
}

// 输出内容转义,防止XSS攻击
echo "<b>User Name:</b><br><br>";
echo htmlspecialchars($USERNAME);
echo "<br><br><b>New Password:</b><br><br>";
echo htmlspecialchars($NEWPASS);

// 转义shell参数,防止命令注入攻击
$escaped_user = escapeshellarg($USERNAME);
$escaped_old_pass = escapeshellarg($PASSWORD);
$escaped_new_pass = escapeshellarg($NEWPASS);

// 执行脚本并获取输出(包含错误信息)
$output = shell_exec("sudo /var/www/html/chngpass.sh $escaped_user $escaped_old_pass $escaped_new_pass 2>&1");

// 显示执行结果
echo "<br><br><b>Execution Result:</b><br><br>";
echo htmlspecialchars($output);
?>
<html>
<br>
<br>
<br>
<script>
function goBack() {
    window.history.back()
}
</script>
<body>
<button onclick="goBack()">Go Back</button>
</body>
</html>

配置sudo权限

编辑sudoers文件(必须用visudo避免语法错误):

sudo visudo

添加一行(假设web用户是www-data),让它能免密执行你的脚本:

www-data ALL=(ALL) NOPASSWD: /var/www/html/chngpass.sh

保存退出后,别忘了给脚本加执行权限:

sudo chmod +x /var/www/html/chngpass.sh
sudo chown root:root /var/www/html/chngpass.sh

内容的提问来源于stack exchange,提问作者Lee Emmery

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:26:53