如何防止PHP命令行脚本中$符号被识别为变量起始符
根因分析
你用escapeshellarg已经正确规避了shell层的变量展开问题,出现$1被替换为换行的核心原因是不同环境下echo命令的默认行为不稳定:部分shell的echo实现会默认解析输入内容里的转义序列,甚至误处理单引号包裹内容里的$+数字组合,导致内容被篡改。
解决方案
你可以根据自己的运行环境选任意一种方案修复:
- 方案1:用
printf替代echo(全平台兼容,最推荐)printf的%s占位符会严格原样输出传入的字符串,不会做任何额外解析,修改后的代码如下:exec('printf "%s" ' . escapeshellarg($text) . ' | script.php'); - 方案2:给
echo加-E参数(适用于Linux/GNU环境)-E参数会强制关闭echo的转义解析逻辑,原样输出内容:exec('echo -E ' . escapeshellarg($text) . ' | script.php'); - 方案3:绕开shell管道直接传递输入(最稳妥,适合复杂内容场景)
直接用proc_open启动子进程,把文本直接写入目标脚本的标准输入,完全绕开shell和中间命令的处理,100%保证内容原样传递:$descriptorspec = [ 0 => ['pipe', 'r'], // 标准输入 1 => ['pipe', 'w'], // 标准输出 2 => ['pipe', 'w'] // 标准错误 ]; $process = proc_open('php script.php', $descriptorspec, $pipes); if (is_resource($process)) { fwrite($pipes[0], $text); fclose($pipes[0]); // 按需读取脚本输出和错误信息 $output = stream_get_contents($pipes[1]); $error = stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); proc_close($process); }
如果修改调用逻辑后问题仍然存在,检查getStdin方法内部是否有额外的正则替换或者转义处理逻辑,原生PHP读取标准输入的file_get_contents('php://stdin')不会篡改任何内容。
内容的提问来源于stack exchange,提问作者GFL
相关产品推荐
相关产品推荐

