批处理脚本错误:“/此时是意外的。”

时间:2015-02-24 17:55:03

标签: batch-file cmd

我写了一个小脚本来显示文本文件的每一行,每个行之间有一个随机的暂停:

SET pauseTime=10
SET maxval=20
SET minval=5
FOR /f %%j in (search1.txt) DO (
    SET pauseTime=%RANDOM% * (%maxval% - %minval% + 1) / 32768 + %minval%
    ECHO.%pauseTime%
    TIMEOUT %pauseTime%
    ECHO.%%j
)

在cmd.exe中运行它给了我:
C:\ Users \ Tim \ Desktop> SET minval = 5
/此时出乎意料。

但是,如果我只是这样做:

FOR /f %%j in (search1.txt) DO (
    ECHO.%%j
)

我打印的所有行都没有错误

发生了什么事?

3 个答案:

答案 0 :(得分:3)

您需要将/A开关添加到SET语句才能进行数学运算。 (我通常还必须删除任何嵌入的空格以使其正常工作。)

SET /A pausetime=%RANDOM%*(%maxval%)-%minval%)/32768+%minval%

您获得的错误也是由批处理器未正确处理for表达式(数字表达式中的嵌套对)中的括号引起的。您可以通过将表达式的那部分分解为单独的变量,然后使用该变量代替括号内的部分来解决这个问题:

SET pauseTime=10
SET maxval=20
SET minval=5
SET /A maxmin=%maxval% - %minval% + 1
FOR /f %%j in (search1.txt) DO (
  SET /A pauseTime=%RANDOM% * %maxmin% / 32768 + %minval%
  ECHO. %pauseTime%
  TIMEOUT %pauseTime%
  ECHO. %j%
)

答案 1 :(得分:1)

这里的问题是因为您使用嵌套( )括号,批处理无法处理并导致您的问题,您可能需要将暂停时间计算拆分为2行。

see this article

  

在评估括号时,CMD shell语句不会使用任何强大的智能,因此例如下面的命令将失败:

     

如果存在MyFile.txt(ECHO一些(更多)土豆)

答案 2 :(得分:1)

如其他答案所述,问题是由嵌套的括号引起的。

您可以通过前面的^个字符逃避而不是避开它们 - 这可行:

IF EXIST MyFile.txt (ECHO Some^(More^)Potatoes)

如果没有插入符号^,命令行解释器将使用第一个)关闭第一个(

但是,将上述转义技术应用于原始问题的代码可以避免错误消息,但会导致工作脚本,即使内部SET被替换为SET /a(如@KenWhite所述),因为你需要建立delayed environment variable expansion;否则,显示的pauseTime值始终是初始值10。以下修复有效:

@ECHO OFF
SET pauseTime=10
SET maxval=20
SET minval=5
SETLOCAL EnableDelayedExpansion
FOR /f %%j in (search1.txt) DO (
    SET /a pauseTime=!RANDOM!*^(maxval-minval+1^)/32768+minval
    ECHO.!pauseTime!
    TIMEOUT !pauseTime!
    ECHO.%%j
)
ENDLOCAL

此处,SETLOCAL语句在FOR命令执行之前启用延迟扩展。在FOR循环的正文中,%pauseTime%%RANDOM%分别由!pauseTime!!RANDOM!取代;那些是受延迟扩展的变量(因为包含!!),这意味着当解析整个FOR命令时,它们不会(像往常一样)扩展,但是当它被执行时。为了易读起见,我从%%命令中的其他变量中删除了SET /a,因为当/a开关存在时不需要它们(请注意,还有一个{{} 1}}运营商支持!!)。

注意:此脚本运行后,%会重置为初始值pauseTime,因为10 / SETLOCAL块构成了新的本地化环境命名空如果您需要最后一个值,请将ENDLOCAL替换为ENDLOCAL;这利用了标准的立即扩展...

尽管如此,由于ENDLOCAL & SET pauseTime=%pauseTime%minval是脚本中的常量,因此只能在maxval之外进行一次计算maxval-minval+1,这与@KenWhite建议的一样。