批处理文件:"Environment Variable Not Defined"



我正在使用一个Java程序,该程序调用一个外部批处理文件并传入一组命令。我在批处理文件中有一个循环,看起来像这样:

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

参数是一堆目录,存储为字符串,如下所示:

String[] commands = {"cmd.exe",
"/C",
"C:UsersuserDocuments", 
"C:UsersuserPictures", 
"C:UsersuserVideos"}

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

Environment variable list[ not defined

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

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

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

EDIT:我重新编写了循环,并添加了一些echo命令,使调试更容易。然而,当我运行批处理文件时,没有任何东西会因为回声而打印到屏幕上,但我仍然会得到相同的错误:

@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[的片段,这在我看来很奇怪。然而,正如我所提到的,它在很长一段时间内都很好。

您发布的代码不能给出错误消息。脚本中一定有其他代码导致了该错误。

只有不带=的SET语句才能给出该错误。在解析和扩展之后,有问题的语句必须看起来像以下语句之一:

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

事实上,如果存在放错地方的引号,那么在=的情况下可能会出现错误。例如,由于忽略了最后一个"之后的所有文本,以下内容将给出该错误:

set "list["1]=value

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

您可以考虑启用ECHO,以便准确地确定错误消息发生的位置。然后你需要弄清楚什么情况会导致这个错误。


更新以响应有问题的"编辑2:">

新发布的代码中的IN()子句几乎可以肯定是生成错误消息的地方。它表示在执行FOR/F循环时没有定义列表"array"。问题是,为什么不呢?需要查找的内容:

  • 是不是有什么东西阻止了定义列表"数组"的早期FOR循环运行?

  • 你确定参数被正确地传递到脚本吗?如果没有参数,那么就不会有数组。

  • 在第二个FOR循环有机会执行之前,是否有东西对数组进行了解锁?

我建议您放入一些诊断ECHO语句来帮助调试。例如,紧接在定义数组的循环之前的ECHO BEFORE 1ST LOOP,以确保正在到达该循环。或者在脚本开始时使用ECHO ARGS = %*,以确保正确传递参数。愉快的侦查:-)

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

@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]!

我在评论中提到了这一点,但我想我会发布一个答案,供其他想知道的人使用:

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

@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 )

谢谢大家的回答!

最新更新