【问题标题】:Batch File: "Environment Variable Not Defined"批处理文件:“未定义环境变量”
【发布时间】:2014-01-08 15:00:25
【问题描述】:

我正在使用一个调用外部批处理文件并传入命令数组的 Java 程序。我在批处理文件中有一个如下所示的循环:

set paramCount=0
for %%x in (%*) do (
    set /A paramCount+=1
    set list[!paramCount!]=%%x
)

参数是一堆目录,存储为字符串,像这样:

String[] commands = {"cmd.exe",
                     "/C",
                     "C:\Users\user\Documents", 
                     "C:\Users\user\Pictures", 
                     "C:\Users\user\Videos"}

如您所见,我的 for 循环应该遍历传递给批处理文件 (%*) 的参数列表并在脚本中模拟一个数组(因为命令数组中的前两个元素用于启动命令进程,只留下要循环的目录)。该程序一直运行良好,直到前几天我突然开始收到一条错误消息:

Environment variable list[ not defined

我根本没有对批处理文件进行任何更改,它似乎无缘无故停止工作。如果有必要的信息,我正在使用流程构建器来运行流程:

ProcessBuilder pb = new ProcessBuilder(commands);
Process p = pb.start();

据说在批处理文件中对数组使用这种语法是可以的,所以我不确定它为什么不接受它。感谢您在此问题上提供的任何帮助。我在使用这个程序时遇到了很多障碍,虽然我已经能够解决其中的 90%,但剩下的 10% 已经开始让我发疯了!谢谢!

编辑: 我重新编写了循环并添加了一些回显命令以使调试更容易。但是,当我运行批处理文件时,由于回显,没有任何内容打印到屏幕上,但我仍然收到相同的错误:

@echo off
setlocal enableDelayedExpansion
set paramCount=0
for %%x in (%*) do (
    echo !paramCount!
    echo %%x
    set list[!paramCount!]=%%x
    set /A paramCount=paramCount+1
)

我还忘了提到当我从 Eclipse 运行 Java 时程序运行良好;它正确调用批处理文件,并且一切都按预期工作。在我将项目导出到可运行的 JAR 并尝试运行它之前,我不会收到错误消息。

编辑 2:

在再次查看我的批处理文件代码后(我之前写过),我发现只有一行看起来可能会导致这个问题。奇怪的是,我使用了在其他地方找到的几乎相同的代码示例来对其进行建模,并且它工作了很长时间而没有给出错误。这是一个循环,旨在循环遍历在第一个循环中创建的列表“数组”的元素:

for /F "tokens=2 delims==" %%d in ('set list[') do (
    set /A paramCount+=1
    set _dir=%%d
    set _dir=!_dir:"=!
    if NOT "%%d"=="nul" set "dirs[!paramCount!]=!_dir!"
)

如您所见,第一行有一段写着set list[,我觉得这很奇怪。但是,正如我所提到的,它在很长一段时间内都运行良好。

【问题讨论】:

  • This answer 可能有帮助
  • 感谢您的链接。不幸的是,我不太确定它是否能帮助我解决这个特定问题。我正在使用延迟扩展来确保 !! 的工作。我确保 %...%s 和 !...!s 使用正确,顺序正确。该问题似乎与 paramCount 有关,因为它似乎只读取变量的 list[ 部分而不是完整的东西(“list[]”)。不太清楚是什么原因造成的。
  • 你使用了 setlocal enabledelayedexpansion 吗? paramCount+=1 最好是 paramCount=!paramCount!+1
  • @mihai_mandis 是的,它是我的批处理文件中的第一行,除了 echo off 语句。至于设置 paramCount,我不知道有什么不同。 += 是否会导致批处理文件出现问题?
  • 应该不会造成问题,但是……我只是想说明一下。请在此处查看使用 %* 时的一些问题stackoverflow.com/questions/20617065/…

标签: java arrays batch-file environment-variables undefined


【解决方案1】:

我在 cmets 中提到了它,但我想我会为其他想知道的人发布一个答案:

如前所述,程序在 Eclipse 中运行良好,批处理文件被调用并按预期运行。但是,在对批处理文件进行一些更改之前,我已经从它们创建了 .exe,并且显然正在运行 .exe 而不是 .bat。这是我的一个非常愚蠢的错误,问题是由先前版本的批处理文件中的一些错误引起的。如果我没记错的话,那个错误是因为“数组元素”是空的。因此,我最终在对其进行操作之前进行了检查以确保它不是空的。以下是我目前正在使用的代码,它按预期工作:

@echo off
setlocal ENABLEDELAYEDEXPANSION
set /A paramCount=-3
for %%x in (%*) do (
    set list[!paramCount!]=%%x
    set /A paramCount=paramCount+1
)
set argA=%list[-3]%
set argB=%list[-2]%
set argC=%list[-1]%
for /F "tokens=2 delims==" %%a in ('set list[-') do SET "%%a="
set list[-3]=""
set list[-2]=""
set list[-1]=""
set paramCount=0
for /F "tokens=2 delims==" %%d in ('set list[') do (
    if not "%%d"=="" (
        set _dir=%%d
        set _dir=!_dir:"=!
        if NOT "%%d"=="nul" set "dirs[!paramCount!]=!_dir!" 
    ) 
    set /A paramCount+=1 )

谢谢大家的回答!

【讨论】:

    【解决方案2】:

    您发布的代码无法给出该错误消息。您的脚本中一定还有其他代码会导致该错误。

    只有没有= 的 SET 语句可能会给出该错误。解析和扩展后,违规语句必须如下所示:

    set list[
    set "list[
    set "list["
    

    实际上,如果引号放错了位置,您可能会在出现= 的情况下收到该错误。例如,以下将给出该错误,因为最后一个 " 之后的所有文本都被忽略:

    set "list["1]=value
    

    1]=value 出现在最后一个 " 之后并被忽略,留下 set "list["

    您可能会考虑启用 ECHO,以便准确定位错误消息发生的位置。然后你需要弄清楚什么条件会导致那个时候的错误。


    更新以响应有问题的“编辑 2:”

    新发布的代码中的那个 IN() 子句几乎肯定是生成错误消息的地方。表示执行 FOR /F 循环时未定义列表“数组”。问题是,为什么不呢?要寻找的东西:

    • 是否有什么东西阻止了之前定义列表“数组”的 FOR 循环的运行?

    • 您确定将参数正确传递给脚本吗?如果没有参数,那么就不会有数组。

    • 在第二个 FOR 循环有机会执行之前,是否有未定义的数组?

    我建议你加入一些诊断 ECHO 语句来帮助调试。例如,ECHO BEFORE 1ST LOOP 紧接在定义数组的循环之前,以确保到达循环。或者 ECHO ARGS = %* 在脚本的开头确保参数被正确传递。快乐的侦探:-)

    【讨论】:

    • 奇怪的是,删除@echo off 语句根本没有帮助。除了该错误消息之外,控制台窗口中绝对不会出现任何内容。至于你的其他建议,我已经非常仔细地检查了我的代码,我没有看到任何不合适的地方。但是,我确实看到一个看起来不正确的语句,但我使用了与另一个源相同的语法并且它工作了很长时间。这是另一个 for 循环,它遍历在我已经发布的循环中创建的列表“数组”。我将在第二次编辑中将其添加到原始帖子中。
    • 这里是我用来写循环的线程:stackoverflow.com/a/18480952/2990189
    • 为了响应您的更新,我在程序的最开始放置了一个回显(回显测试),但错误立即出现,而没有将“测试”打印到控制台。我检查了 Java 代码以确保所有命令在传递到流程构建器时都是正确的。我也试过 echo %* 没有运气。错误立即出现。如果那行得通,我相信我现在可以缩小范围,因为我尝试在各个区域的代码中放置 echo 调试语句。然而,它们都没有被打印出来,这就是我在这里发布问题的原因。
    • 好吧,请原谅我的愚蠢。我完全忘记了我从旧的 bat 文件中制作了一个 exe,而这就是我一直在运行的——exe。所以每次我编辑bat文件时,exe都是一样的。我打算再做一些“侦查”,但这次使用批处理文件进行测试 =P
    【解决方案3】:

    我尝试了下面的代码,从命令行调用时它对我有用。

    @echo off
    setlocal enabledelayedexpansion
    
    set paramCount=0
    
    for %%x in (%*) do (
        set /A paramCount=!paramCount!+1
        set list[!paramCount!]=%%x
    )
    echo !list[1]!
    echo !list[2]!
    echo !list[3]!
    

    【讨论】:

    • 不幸的是,我仍然遇到问题。我重新安排了循环中的一些代码,并添加了一些“回显”命令以查看发生了什么。我已将代码发布到我的原始编辑中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    相关资源
    最近更新 更多