Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows批处理:findstr未在for循环中设置ERRORLEVEL_Windows_Batch File_Cmd_Windows 10_Command Prompt - Fatal编程技术网

Windows批处理:findstr未在for循环中设置ERRORLEVEL

Windows批处理:findstr未在for循环中设置ERRORLEVEL,windows,batch-file,cmd,windows-10,command-prompt,Windows,Batch File,Cmd,Windows 10,Command Prompt,有人能解释一下为什么下面的代码片段会打印0: @echo off setlocal for /f %%i in ('cmd /c echo blah') do ( echo %%i | findstr bin > NUL echo %ERRORLEVEL% ) 在for循环之外添加另一条等效语句时,它将打印1: @echo off setlocal echo blah | findstr bin > NUL echo %ERRORLEVEL% for /f %

有人能解释一下为什么下面的代码片段会打印
0

@echo off
setlocal

for /f %%i in ('cmd /c echo blah') do (
    echo %%i | findstr bin > NUL
    echo %ERRORLEVEL%
)
在for循环之外添加另一条等效语句时,它将打印
1

@echo off
setlocal

echo blah | findstr bin > NUL
echo %ERRORLEVEL%

for /f %%i in ('cmd /c echo blah') do (
    echo %%i | findstr bin > NUL
    echo %ERRORLEVEL%
)
我对批处理有点生疏,所以这对我来说有点神秘,因为这两个语句似乎不相关。在此方面的任何帮助都将不胜感激,谢谢

更新:

如果您将您的
echo%ERRORLEVEL%
语句放在for语句的结束
之后,它将按预期工作

for /f %%i in ('cmd /c echo blah') do (
    echo %%i | findstr bin > NUL
)
echo %ERRORLEVEL%
我在这里有点猜测,因为确切的“确定”原因,但肯定是
setlocal
引起的。我假设for循环中ERRORLEVEL的值是
cmd/c…
语句的结果。这似乎是一种奇怪的行为,但我在批处理文件中见过更糟糕的行为

如果在开始时删除
setlocal
,它将正常工作

原件:

findstr
在运行时设置
errorlevel
。因此,
echo%errorlevel%
将始终输出0

例如,下面的findstr语句是成功的,因此它输出匹配的行(传递给它的唯一行):

此语句未成功(findstr不输出任何内容)且errorlevel设置为1时:

C:\>echo blah_in | findstr bin
C:\>echo %errorlevel%
1            ; failed
更新:

如果您将您的
echo%ERRORLEVEL%
语句放在for语句的结束
之后,它将按预期工作

for /f %%i in ('cmd /c echo blah') do (
    echo %%i | findstr bin > NUL
)
echo %ERRORLEVEL%
我在这里有点猜测,因为确切的“确定”原因,但肯定是
setlocal
引起的。我假设for循环中ERRORLEVEL的值是
cmd/c…
语句的结果。这似乎是一种奇怪的行为,但我在批处理文件中见过更糟糕的行为

如果在开始时删除
setlocal
,它将正常工作

原件:

findstr
在运行时设置
errorlevel
。因此,
echo%errorlevel%
将始终输出0

例如,下面的findstr语句是成功的,因此它输出匹配的行(传递给它的唯一行):

此语句未成功(findstr不输出任何内容)且errorlevel设置为1时:

C:\>echo blah_in | findstr bin
C:\>echo %errorlevel%
1            ; failed
这应该行得通

cmd中的for循环从技术上讲是一行,因此变量只展开一次。使用感叹号而不是百分比和“ENABLEDELAYEDEXPANSION”应该可以解决这个问题

这应该行得通


cmd中的for循环从技术上讲是一行,因此变量只展开一次。使用感叹号而不是百分数和“ENABLEDELAYEDEXPANSION”应该可以解决这个问题。

问题是在
代码块
(括号内的一系列语句)中,任何
%var%
都将替换为
解析时变量的实际值

在您的第一个示例中,
%errorlevel%
0
,并以这样的方式进行回音。在第二个示例中,遇到
时,它是
1
,因此它被
1
替换

如果要显示可能在循环中更改的环境变量的值,则需要执行以下三项操作之一:

  • 调用
    setlocal enabledelayedexpansion
    并回显
    !瓦尔而不是
    %var%
    -请注意,可以激活的嵌套
    setlocal
    指令数量有限

  • 调用子程序

  • 利用语法漏洞

  • 有很多很多关于延迟扩展的文章

    粗略地说,您可以简单地使用(注意-除了循环控制变量(
    metavariable
    -
    %%i
    在本例中),case在批处理中基本上是无关的)

    另一种方法是动态调用
    setlocal

    @echo off
    setlocal
    
    echo blah | findstr bin > NUL
    echo %ERRORLEVEL% or !errorlevel!
    for /f %%i in ('cmd /c echo blah') do (
        echo %%i | findstr bin > NUL
        setlocal ENABLEDELAYEDEXPANSION
        echo %ERRORLEVEL% or !errorlevel!
        endlocal    
    )
    
    这样做的缺点是,
    endlocal
    会回退自上次
    setlocal
    以来对环境所做的任何更改。还要注意,如果
    delayedexpansion
    无效,
    不再是特殊字符

    或者,您可以以传统方式使用
    errorlevel

    @echo off
    setlocal
    
    echo blah | findstr bin > NUL
    echo %ERRORLEVEL% or !errorlevel!
    
    for /f %%i in ('cmd /c echo blah') do (
        echo %%i | findstr bin > NUL
        if errorlevel 1 (echo errorlevel is 1 or greater
        ) else (echo errorlevel is 0
        )
    )
    
    请注意,这将查看
    errorlevel
    运行时
    值,如果errorlevel n
    表示“如果errorlevel为n或大于n

    或-调用子例程:

    @echo off
    setlocal
    
    echo blah | findstr bin > NUL
    echo %ERRORLEVEL% or !errorlevel!
    for /f %%i in ('cmd /c echo blah') do (
        echo %%i | findstr bin > NUL
        call :show
    )
    goto :eof
    
    :show
    echo %ERRORLEVEL%
    goto :eof
    
    注意这里的
    goto:eof
    (这里冒号很重要-这意味着“转到文件的物理结尾”

    或者,使用子例程的特殊版本—语法漏洞

    @echo off
    setlocal
    
    echo blah | findstr bin > NUL
    echo %ERRORLEVEL% or !errorlevel!
    for /f %%i in ('cmd /c echo blah') do (
        echo %%i | findstr bin > NUL
        call echo %%errorlevel%%
    )
    

    问题是在
    代码块
    (括号内的一系列语句)中,任何
    %var%
    都将在
    解析时被变量的实际值替换

    在第一个示例中,
    %errorlevel%
    0
    并以这样的方式进行回音。在第二个示例中,当遇到
    for
    时,它是
    1
    ,因此它被
    1
    替换

    如果要显示可能在循环中更改的环境变量的值,则需要执行以下三项操作之一:

  • 调用
    setlocal enabledelayedexpansion
    和echo
    !var!
    ,而不是
    %var%
    ——注意,可以激活的嵌套
    setlocal
    指令的数量是有限的

  • 调用子程序

  • 利用语法漏洞

  • 有很多很多关于延迟扩展的文章

    粗略地说,您可以简单地使用(注意-除了循环控制变量(
    metavariable
    -
    %%i
    在本例中),case在批处理中基本上是无关的)

    另一种方法是动态调用
    setlocal

    @echo off
    setlocal
    
    echo blah | findstr bin > NUL
    echo %ERRORLEVEL% or !errorlevel!
    for /f %%i in ('cmd /c echo blah') do (
        echo %%i | findstr bin > NUL
        setlocal ENABLEDELAYEDEXPANSION
        echo %ERRORLEVEL% or !errorlevel!
        endlocal    
    )
    
    这样做的缺点是
    endlocal
    会对任何更改进行回退
    @echo off
    setlocal enabledelayedexpansion
    
    :::This part is not exactly necessary but it creates the file dictionary.txt and the var - this
    echo.word>dictionary.txt
    set this=notaword
    
    :::So instead of checking for errorlevel just check for a space in the output
    :middle
    for /f "tokens=*" %%a in ('findstr /n /b /c:%this% dictionary.txt') do (
      set "output=%%a"
      goto :yeah
    )
    :yeah
    if exist %output% (""," "
        goto :oops
    ) else (
        goto :nice
    )
    :oops
    echo.%this% is NOT a word
    pause & set this=word & goto :middle
    :nice
    echo.%output%
    pause