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

Windows Batch脚本报错:) was unexpected at this time(退出码255)

Jenkins IMPI部署脚本报错排查:) was unexpected at this time

问题背景

接手Jenkins上的IMPI部署脚本,原脚本将Jenkins凭证写入明文文件后传给mpiexec。为验证功能,修改为直接向mpiexec传入明文凭证,执行时出现) was unexpected at this time错误,脚本返回退出码255。

报错日志

ccr\******* c:\iusers\jenkins\workspace\impi_PR-3056_qy6gczv2>mpiexec -register -username CCR\****** -password **** 

[2022-09-22T18:39:50.318Z] credentials were saved.

[2022-09-22T18:39:50.318Z] ) was unexpected at this time.

[2022-09-22T18:39:50.318Z] ccr\********c:\iusers\jenkins\workspace\impi_PR-3056_qy6gczv2>) else if /i "ONEAPI" equ "PSXE" (

script returned exit code 255

相关Groovy代码

package impi

import infra.util.*

public class Deploy {
    final private def script
    final private String artifactsDir
    final private def params
    final private String siteId

    public Deploy(final def script, final String artifactsDir, final def params, final String siteId) {
        this.script = script
        this.artifactsDir = artifactsDir
        this.params = params
        this.siteId = siteId
    }

    public void deployLinux() {
        script.withEnv([
            "PACKAGE_INSTALL_LAYOUT=${params.PACKAGE_INSTALL_LAYOUT ?: 'ONEAPI'}",
            "artifacts_dir=${artifactsDir}",
            "ONEAPI_GLOB=${Consts.OS_CUSTOMIZED_VARS.linux.oneapiPackageMask}",
            "PSXE_GLOB=${Consts.OS_CUSTOMIZED_VARS.linux.psxePackageMask}"
        ]) {
            script.sh('''#!/bin/bash
                set -ex -o pipefail
                # Package specifications
                ONEAPI_DIR_NAME="oneapi_impi"
                PSXE_DIR_NAME="psxe_impi"
                ###
                PACKAGE_INSTALL_LAYOUT=${PACKAGE_INSTALL_LAYOUT:-ONEAPI}
                echo "DEBUG: Install package for ${PACKAGE_INSTALL_LAYOUT} configuration"
                selector_glob="${PACKAGE_INSTALL_LAYOUT}_GLOB"
                selector_dirname="${PACKAGE_INSTALL_LAYOUT}_DIR_NAME"
                package_path=$( ls -1 $artifacts_dir/${!selector_glob} )
                package_target_dir_name=${!selector_dirname}
                tar xfz $package_path
                pushd $( basename $package_path .tgz ) > /dev/null
                    unzip -P accept package.zip
                    ./install.sh -s -d $artifacts_dir/$package_target_dir_name
                    echo "DEBUG: Package in ${PACKAGE_INSTALL_LAYOUT} configuration successfully installed to $artifacts_dir/$package_target_dir_name dir"
                popd > /dev/null
                echo "DEBUG: Enable ${PACKAGE_INSTALL_LAYOUT} testing layout"
                ln -s $artifacts_dir/$package_target_dir_name $artifacts_dir/impi
            ''')
        }
    }

    public void deployWindows() {
        script.withEnv([
            "ARTIFACTS_DIR=${Utils.getWindowsPath(script, artifactsDir, "^/p/", BaseConsts.CIFS_SERVER_v0[siteId])}", // Autogen archive is always here
            """MPI_ARCHIVE_PATH=${params.MPI_ARCHIVE_PATH ?
                Utils.getWindowsPath(script, params.MPI_ARCHIVE_PATH, "^/p/", BaseConsts.CIFS_SERVER_v0[siteId]) :
                Utils.getWindowsPath(script, artifactsDir, '^/p/', BaseConsts.CIFS_SERVER_v0[siteId])}""",
            "PSXE_PACKAGE_MASK=${Consts.OS_CUSTOMIZED_VARS.windows.psxePackageMask}",
            "ONEAPI_PACKAGE_MASK=${Consts.OS_CUSTOMIZED_VARS.windows.oneapiPackageMask}",
            "TOOLS_DIR=${Utils.getWindowsPath(script, BaseConsts.CIFS_TOOLS_DIR_v0, "^/p/", BaseConsts.CIFS_SERVER_v0[siteId])}",
            "CYGWIN_DIR=${BaseConsts.CYGWIN_DIR}",
            "SRC_DIR=${Consts.WINDOWS_SRC_DIR}",
            "PACKAGE_INSTALL_LAYOUT=${params.PACKAGE_INSTALL_LAYOUT ?: 'ONEAPI'}"
        ]) {
            script.withCredentials([script.usernamePassword(credentialsId: 'ec25177f-b239-43cb-a2d5-874a88f97fc9', passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) {
              script.bat('''
                   PATH=%TOOLS_DIR%\\\\unzip-5.51-1-bin\\\\bin;%CYGWIN_DIR%\\\\bin;%PATH%
                   REM Create a source dir in local workspace
                   if exist %SRC_DIR% rmdir /s/q %SRC_DIR%
                   if %errorlevel% neq 0 exit /b %errorlevel%
                   mkdir %SRC_DIR%
                   REM Obtain IMPI sources with autogen results
                   copy %MPI_ARCHIVE_PATH%\\\\impi_src.tgz .
                   copy %ARTIFACTS_DIR%\\\\workspace-1-autogen.tgz .
                   tar -xzf impi_src.tgz -C %SRC_DIR%
                   if %errorlevel% neq 0 exit /b %errorlevel%
                   tar -xzf workspace-1-autogen.tgz -C %SRC_DIR%
                   icacls %SRC_DIR% /remove sys_ctlab
                   icacls %SRC_DIR% /Q /grant sys_ctlab:(OI)(CI)F /T
                   icacls %SRC_DIR%
                   echo "INFO: Deploy %PACKAGE_INSTALL_LAYOUT% package layout"
                   REM (echo CCR\\\\%USERNAME%& echo %PASSWORD%& echo %PASSWORD%) > auth_data.txt
                   mpiexec -register -username CCR\\\\****** -password ****

                   REM Obtain IMPI packages and configure services
                   if /i "%PACKAGE_INSTALL_LAYOUT%" equ "ONEAPI" (
                       copy %MPI_ARCHIVE_PATH%\\\\%ONEAPI_PACKAGE_MASK% .
                       unzip -o -P"accept" %ONEAPI_PACKAGE_MASK%
                       if %errorlevel% neq 0 exit /b %errorlevel%
                       bin\\\\hydra_service.exe -install
                       if %errorlevel% neq 0 exit /b %errorlevel%
                       env\\\\vars.bat
                       if %errorlevel% neq 0 exit /b %errorlevel%
                       REM TODO: Fix the mpiexec register call w/ credentials
                       REM type auth_data.txt | mpiexec -register
                       REM if %errorlevel% neq 0 exit /b %errorlevel%
                   ) else if /i "%PACKAGE_INSTALL_LAYOUT%" equ "PSXE" (
                       copy %MPI_ARCHIVE_PATH%\\\\%PSXE_PACKAGE_MASK% .
                       unzip -o -P"accept" %PSXE_PACKAGE_MASK%
                       if %errorlevel% neq 0 exit /b %errorlevel%
                       intel64\\\\bin\\\\hydra_service.exe -install
                       if %errorlevel% neq 0 exit /b %errorlevel%
                       intel64\\\\bin\\\\mpivars.bat
                       if %errorlevel% neq 0 exit /b %errorlevel%
                       REM TODO: Fix the mpiexec register call w/ credentials
                       REM type auth_data.txt | mpiexec -register
                       REM if %errorlevel% neq 0 exit /b %errorlevel%
                   ) else (
                       echo "ERROR: PACKAGE_INSTALL_LAYOUT=%PACKAGE_INSTALL_LAYOUT% is not correct! Please use PSXE or ONEAPI."
                       exit /b 1
                   )
                   del auth_data.txt
                '''.stripIndent())
            }
        }
    }

    public void uninstallWindows() {
        script.withEnv([
            "PACKAGE_INSTALL_LAYOUT=${params.PACKAGE_INSTALL_LAYOUT ?: 'ONEAPI'}"
        ]) {
            script.bat('''
                if /i "%PACKAGE_INSTALL_LAYOUT%" equ "ONEAPI" (
                    if exist "bin\\\\hydra_service.exe" bin\\\\hydra_service.exe -remove
                    if %errorlevel% neq 0 exit /b %errorlevel%
                    rem rmdir /s /q "bin"
                    rem if %errorlevel% neq 0 exit /b %errorlevel%
                ) else if /i "%PACKAGE_INSTALL_LAYOUT%" equ "PSXE" (
                    if exist "intel64\\\\bin\\\\hydra_service.exe" intel64\\\\bin\\\\hydra_service.exe -remove
                    if %errorlevel% neq 0 exit /b  %errorlevel%
                    rem rmdir /s /q "intel64\\\\bin"
                    rem if %errorlevel% neq 0 exit /b %errorlevel%
                ) else (
                    echo "ERROR: PACKAGE_INSTALL_LAYOUT=%PACKAGE_INSTALL_LAYOUT% is not correct! Please use PSXE or ONEAPI."
                )
            '''.stripIndent())
        }
    }
}

问题排查与解决方法

核心原因分析

从报错日志和代码来看,触发错误的核心原因有两个:

  1. 批处理调用外部脚本未加call:如果mpiexec是.bat/.cmd批处理文件而非可执行程序,直接执行会夺走当前批处理的控制权,后续代码会被当作独立命令执行,导致else if的)被单独解析,引发语法错误。
  2. 密码含特殊字符破坏批处理语法:如果密码包含&、(、)、!等批处理特殊字符,直接传入会被解析为命令的一部分,打乱后续代码结构。

针对性修复方案

方案1:添加call命令调用mpiexec

修改deployWindows方法中的mpiexec调用行,添加call确保当前批处理能继续执行后续代码,同时用引号包裹参数避免分割错误:

call mpiexec -register -username "CCR\\%USERNAME%" -password "%PASSWORD%"

方案2:恢复文件传递凭证的方式(更稳妥)

如果密码存在特殊字符,建议回到原方案,通过文件传递凭证,既避免直接暴露凭证,又规避语法问题:

REM 恢复凭证写入文件的逻辑
(echo CCR\\%USERNAME%& echo %PASSWORD%& echo %PASSWORD%) > auth_data.txt
type auth_data.txt | call mpiexec -register

执行完成后保留原代码中的del auth_data.txt步骤,清理临时文件。

方案3:处理特殊字符(若必须直接传参)

如果坚持直接传参,启用延迟变量扩展来处理特殊字符:
在批处理开头添加setlocal enabledelayedexpansion,然后用!PASSWORD!代替%PASSWORD%:

setlocal enabledelayedexpansion
call mpiexec -register -username "CCR\\!USERNAME!" -password "!PASSWORD!"
endlocal

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:15:50