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

Linux下ProcessBuilder执行sonar-scanner报error=2找不到文件问题

问题原因

你遇到的error=2, No such file or directory报错不是路径拼接错误导致的,Windows能正常运行、Linux下文件存在却启动失败,是四个Linux环境特有问题导致的:

  • sh -c调用方式错误。sh -c的语法要求后续所有待执行命令必须作为单个完整字符串传入,你当前代码把sonar-scanner和后续参数逐个加入命令列表,实际执行时sh只会识别第一个参数为执行命令,后续参数会被识别为sh本身的位置参数,不会传给sonar-scanner,直接导致命令解析失败。
  • 可执行权限缺失。Linux下文件存在但没有+x执行权限时,Java的ProcessBuilder启动程序会抛出和“文件不存在”完全相同的报错,属于常见的误导性异常信息。
  • 脚本解释器不匹配。官方sonar-scanner启动脚本的首行shebang默认是#!/bin/bash,如果你的Linux运行环境是精简版(比如Alpine容器),默认没有安装bash、只有sh,哪怕脚本文件本身存在,也会因为找不到解释器抛出这个错误。
  • 隐性路径问题:你当前传入的是相对路径sonar-scanner,部分OpenJDK版本在Linux环境下不会优先从ProcessBuilder设置的工作目录检索可执行文件,也会触发找不到文件的报错。
修复步骤
  1. 先做环境前置校验
    进入sonar-scanner所在的bin目录,执行以下命令:
    # 给启动脚本加全局可执行权限
    chmod +x sonar-scanner
    # 检查脚本首行的解释器路径,如果输出#!/bin/bash但当前环境没有bash,要么安装bash,要么把首行改为#!/bin/sh
    head -n 1 sonar-scanner
    
  2. 修正代码逻辑,去掉不必要的sh/cmd套壳调用,直接传入可执行文件的绝对路径,避免参数解析问题:
    // 提前引入java.util.Arrays、java.io.File类
    String jarPath = utility.findJarLocation();
    ArrayList<String> commandList = new ArrayList<>();
    // 用系统自带的文件分隔符拼接路径,避免跨平台兼容问题
    String scannerBinDir = jarPath + File.separator + "sonarScanner" + File.separator + "bin";
    
    if (parameters.getSistemaOperativo().equals("w")) { // Windows环境
        commandList.add(scannerBinDir + File.separator + "sonar-scanner.bat");
    } else { // Linux、Mac环境
        String scannerExecPath = scannerBinDir + File.separator + "sonar-scanner";
        File scannerFile = new File(scannerExecPath);
        // 代码层面主动设置可执行权限,避免手动配置遗漏
        if (scannerFile.exists() && !scannerFile.canExecute()) {
            scannerFile.setExecutable(true, false);
        }
        commandList.add(scannerExecPath);
    }
    
    // 注意:如果参数包含带空格的带引号值,不要用简单空格拆分,会破坏参数结构
    String[] scannerParams = parameters.getSonarScannerParameters().trim().split("\\s+");
    commandList.addAll(Arrays.asList(scannerParams));
    
    ProcessBuilder pb = new ProcessBuilder(commandList);
    pb.directory(new File(scannerBinDir));
    pb.redirectErrorStream(true);
    Process pr = pb.start();
    
  3. 额外优化:如果后续遇到带空格的sonar参数(比如项目路径含空格、配置值含空格),建议替换简单的split(" ")逻辑为正规的命令行参数分词逻辑,避免参数传递错误。

内容的提问来源于stack exchange,提问作者Andrea Chirigu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:31:01