执行mysqldump生成空文件,脚本返回正常却无内容求助
我来帮你拆解这个问题,你遇到的情况其实挺常见的,主要是几个细节没处理到位,咱们一步步来分析:
1. 你的执行结果判断逻辑搞反了(核心问题)
你用>把mysqldump的标准输出重定向到文件后,exec()的$output变量根本捕获不到有效内容——因为所有正常输出都被写到文件里了。但你说脚本输出了“GOOD”,这说明$output不为空,大概率是mysqldump把错误信息输出到了标准输出(而非常规的标准错误流),导致你的判断逻辑完全失效。
正确的做法是依赖exec()的返回码(0表示命令执行成功,非0表示失败),同时把标准错误重定向到标准输出,这样就能捕获到所有错误信息:
// 把stderr重定向到stdout,方便捕获错误 $string = 'mysqldump -u'.$db->user.' -p'.$db->pass.' '.$db->db.' > /home/user/public_html/'.$filename.' 2>&1'; // 捕获返回码(第三个参数) exec($string, $output, $returnCode); if ($returnCode === 0) { echo "GOOD"; } else { // 输出错误信息方便排查 echo "Error: " . implode("\n", $output); }
2. 密码传递的shell转义坑
如果你的数据库密码包含特殊字符(比如$、!、&、#这类shell元字符),直接拼到命令里会被shell解析篡改,导致实际传递给mysqldump的密码不正确,自然导出为空。
解决办法是用escapeshellarg()把每个参数都转义成安全的shell字符串,同时推荐用--password=的形式传递密码(比-p更直观,避免空格问题):
// 转义所有参数,避免特殊字符干扰 $user = escapeshellarg($db->user); $pass = escapeshellarg($db->pass); $dbName = escapeshellarg($db->db); $filePath = escapeshellarg('/home/user/public_html/'.$filename); $string = "mysqldump -u$user --password=$pass $dbName > $filePath 2>&1"; exec($string, $output, $returnCode);
3. 数据库权限不足
运行PHP的用户(通常是web服务器用户,比如www-data)对应的数据库账号,需要具备以下权限才能正常导出:
SELECT权限:读取表数据的基础权限LOCK TABLES权限:mysqldump默认会锁表保证数据一致性(如果是InnoDB表,可以加--single-transaction参数绕过锁表,但仍需SELECT权限)
你可以手动用该账号登录MySQL,执行SHOW GRANTS;查看权限是否足够。
4. 路径/文件名的潜在问题
虽然mysqldump --help能正常写入文件,但还是要确认$filename是否包含空格、特殊字符等,没转义的话shell会把它拆成多个参数,导致写入到错误的位置(甚至创建多个无效文件)——用上面的escapeshellarg()处理文件路径就能避免这个问题。
内容的提问来源于stack exchange,提问作者Dawson Irvine

