【问题标题】:error: call was unexpected at this time when i use call command behind if judgment错误:此时调用是意外的,当我在if判断后面使用call命令时
【发布时间】:2018-01-31 14:10:52
【问题描述】:

我在 bat 命令和学习方面比较新。我遇到了一个问题,我无法解决它。 如果judge.my bat文件在下面,当我在后面调用调用命令时,它会导致“调用”是意外的错误。 求大家帮忙解决一下。非常感谢。请

test1.bat

@echo off
echo test1.bat running
set value=%1
set param=t1

if %errorlevel%==0 goto:dif

:dif
if %value%==%param% call test2.bat

pause

test2.bat

@echo off

echo test2.bat running

当我输入 test1 t1 时它什么都不会,但是当我在 cmd 中输入 test1 命令行时发生错误。


好的,我现在更改问题并更新 test1.bat 文件。

test1.bat

@echo off
echo test1.bat running
set "value=t1"

if  "%value%==-t1"  call "test2.bat"
if  "%value%==t1"   echo ok

我输入test1命令行也出现同样的错误。

错误:此时调用意外

我想知道为什么会导致这个错误。

【问题讨论】:

  • 你期待t1==!t1!吗?因为显然不是!
  • possible duplicate(尽管标题具有误导性)
  • 对不起,它应该显示为%value%==%param%,我忘了删除感叹号..
  • @SnailMann 是否要匹配 %1 的一部分,所以要匹配 test1 中的 t1
  • @GerhardBarnard 是的,如果我在 cmd 中输入 test t1,我想运行函数 dif。只需 %1(第二个参数)匹配 t1 成功。

标签: batch-file cmd


【解决方案1】:

以下是您提供的脚本中相关行的快速示例:

test1.bat

@Echo Off
Echo %~nx0 running
Set "value=%~1"
Set "param=t1"
If /I "%value%"=="%param%" Call "test2.bat"
Pause

test2.bat

@Echo Off
Echo %~nx0 running

它应该向您展示如何动态引用脚本名称、如何使用双引号作为保护值或字符串的最佳实践以及如何使用If 进行条件验证。

有关命令的信息,只需在命令提示符下输入CommandName /?;即Set /?If /?Call /?

【讨论】:

  • 这只会匹配%1的完整字符串是t1并且不会匹配test1
  • @Gerhard,我的阅读是 OP 输入 test1 t1 这运行 test1.bat 与参数 t1 作为 %1。他们在输入test1时报错,因为他们在没有参数的情况下运行test1.bat。因此,他们的代码 undefined 变量 %value% 意味着 if ==!%param%! call test2.bat 正在尝试运行。
  • 是的,我现在让他澄清一下,我非常关注他在最后一行中声明的最后一行“但是当我在 cmd 中输入 test1 命令时出现错误” 所以我也只是假设他想在test1 中匹配t1 :)
  • 所以我们几乎都是正确的,他想将%2t1 匹配,以便您更新答案。
  • 是的,他们在 cmd.exe 中输入了命令test1,在此之前他们输入了test1 t1。因为.bat 包含在%PATHEXT% 中,所以无需使用其扩展名即可运行,否则它们在命令提示符下的命令将是test1.cmd t1test1.cmd
【解决方案2】:

不清楚你在输入什么。

如果执行命令test1 t1

然后:

value 将获取值 t1(从命令行尾部)
param 将获取值 t1
errorlevel 将设置为 0 作为 @ 987654328@成功了,所以

if %errorlevel%==0 goto:dif

将转到:dif,因为errorlevel (%errorlevel%) 的内容00==0

这里有个小困难,因为如果errorlevel 不是 0,那么if 条件将not 执行goto dif(冒号最好省略),因此该过程将继续 - 在任何情况下都将标记为 :dif...

if %value%==!%param%! call test2.bat

将通过替换当前值来评估并执行

if t1==!t1! call test2.bat

因为valueparam 都包含t1
但是t1 等于!t1!,所以call 指令将被忽略。


如果你执行命令test1

value 将获取值 nothing(因为没有命令行尾部)
param 将获取值 t1
errorlevel 将被设置到0 因为set 成功了,所以

if %errorlevel%==0 goto:dif

将转到:dif,因为errorlevel (%errorlevel%) 的内容00==0

if %value%==!%param%! call test2.bat

将通过替换当前值来评估并执行

if ==!t1! call test2.bat

因为value 包含nothingparam 包含t1

这是一个语法错误,因为 cmd 期望

if <i>string1</i>==<i>string2</i> ...


另一个问题是!something!的使用。

通常,! 只是另一个字符,例如 xq 批量,%var% 表示 the content of the variable "var"

当您有一个代码块(括号内的一系列命令)时,批处理首先将var 的值替换为%var%,然后执行命令,所以

set "var=original"
for %%a in (1 2 3) do (
  rem this is a code block
  echo before %var%
  set "var=modified"
  echo after  %var%
)
echo then  %var%

将报告originaloriginal 3 次和modified,因为实际执行的是

set "var=original"
for %%a in (1 2 3) do (
  rem this is a code block
  echo before original
  set "var=modified"
  echo after  original
)
echo then  %var%

当特殊命令时这会改变

setlocal enabledelayedexpansion

被执行。 ! 则具有特殊含义。

set "var=original"
setlocal enabledelayedexpansion
for %%a in (1 2 3) do (
  rem this is a code block
  echo before %var% !var! 
  set "var=modified"
  echo after  %var% !var!
)
echo then  %var% !var!
endlocal
echo final %var% !var!

在这种情况下,报告将是

原作之前
原版修改后
原始修改前
原版修改后
原始修改前
原版修改后
然后修改修改
最终原创!var!

因为%var% 指的是原始 值,而!var! 指的是修改 值(因此在第一个before,变量还没有被修改了,但是在after,变量已经被修改了,所以第二个和第三个循环将modified的值报告为!var!)

循环之后,%var%!var! 都报告相同的内容(值在循环内被修改,但不是在循环结束后)。

最后,endlocaldelayedexpansion 关闭,因此! 再次成为普通字符,endlocal 也会丢弃在执行setlocal 之后对变量所做的任何修改。因此显示了var 的原始值(就像执行setlocal 时一样)并且!var! 不再是一个特殊的字符串。

所以 - 你的

if %value%==!%param%! call test2.bat

会,如果setlocal enabledelayedexpansion 已被执行 并且param 包含t1 实际执行

if <i>the value contained in "value"</i>==<i>the value contained in "t1"</i> call test2.bat

【讨论】:

  • 好的!感谢您的详细回答,我明白您对如何使用“setlocal enabledelayedexpansion”命令和“!”的意思。谢谢。但是我想知道为什么当我在 cmd.exe.Pls ingore 中输入 test1 命令行时,此时它会报告调用是意外的!符号。
  • 不清楚您的 actual 命令条目是什么。如果您输入的只是“test1”,那么请阅读上面的第二个块,从If you execute the command test1 开始,我已经逐步展示了发生的情况。请注意,在 cmets 中,您可以在要突出显示的文本的开头和结尾使用单个星号更改为 斜体如果您使用两个星号,您将获得粗体文本
  • 好的,我现在更新我的问题,解释更清楚了。请帮助检查并找到 casue.thx
  • 很好。现在我们确定输入的是什么。 :) 所以 - 请重新阅读我的回复,在第二部分开始“如果你执行命令 test1”并忽略 ! 字符,因为它们现在已被删除,关于 delayedexpansion 的传奇现在不是相关的。
猜你喜欢
  • 2017-11-22
  • 2016-03-25
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
  • 2016-04-13
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多