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

如何防止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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 02:42:01