草庐IT

windows - 命令脚本退出代码未被同一行 && 或 || 看到?

coder 2023-11-11 原文

考虑一个名为 t.cmd 的命令脚本,它只包含以下两行:

@exit /b 123
@echo If you see this, THEN EXIT FAILED..

因此,该脚本只是将脚本执行过程的退出代码设置为123,并没有杀死cmd.exe。最后的 echo 确认退出实际上导致立即返回(它的输出不应该出现)。

现在执行这个脚本,然后打印出%errorlevel%:

>t.cmd

>echo %errorlevel%
123

到目前为止一切顺利:一切都完全符合预期。

但现在在一行中执行以上所有内容,使用 && 进行条件执行:

>t.cmd && echo %errorlevel%
123

我不希望这样:如果 t.cmd 真的以非 0 退出代码返回,那么它应该停止执行 &&(即回显)之后的所有内容。我们看到它打印的事实意味着它确实执行了。这到底是怎么回事?

如果在一行中执行上述所有操作,使用 ||对于条件执行:

>t.cmd || echo %errorlevel%

>

此行为也与我的预期相反(尽管它与上面的 && 行为一致)。

请注意,这种奇怪的行为仅适用于 bat 文件,但不适用于“原始命令”。

证明:考虑以下命令行交互,我尝试执行虚假命令 abcdef 而不是调用 t.cmd:

>abcdef
'abcdef' is not recognized as an internal or external command,
operable program or batch file.

>echo %errorlevel%
9009

>abcdef && echo %errorlevel%
'abcdef' is not recognized as an internal or external command,
operable program or batch file.

>abcdef || echo %errorlevel%
'abcdef' is not recognized as an internal or external command,
operable program or batch file.
9009

在这里,&& 和||立即查看失败的伪造命令的退出代码。

那么为什么 cmd 文件的行为不同?

已在 File redirection in Windows and %errorlevel% 中观察到 cmd.exe 中可能相关的错误

此外,我知道 ERRORLEVEL is not %ERRORLEVEL%

顺便说一句,上面的代码都是在 Win 7 Pro 64 位机器上执行的。我不知道其他版本的 Windows 的行为如何。

最佳答案

t.bat稍作修改如下:

@exit /b 123%~1
@echo If you see this, THEN EXIT FAILED..

想出下一个输出:

==>t.bat 1

==>echo %errorlevel%
1231

==>t.bat 2&echo %errorlevel%
1231

==>echo %errorlevel%
1232

==>cmd /V /C t.bat 3^&echo !errorlevel!
1233

==>echo %errorlevel%
0

==>cmd /V /C t.bat 4^&echo !errorlevel!^&exit /B !errorlevel!
1234

==>echo %errorlevel%
1234

==>

资源

编辑启发EnableDelayedExpansion:

==>cmd /v
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

==>t.bat 5&echo !errorlevel!
1235

==>echo %errorlevel%
1235

==>

编辑 2 启发(或混淆?)&&||。将下一个代码片段保存为 errlevels.cmd:

@ECHO ON >NUL
@SETLOCAL enableextensions enabledelayedexpansion
(call )
@echo ^(call ^) command clears errorlevel %errorlevel%
abcd /G>NUL 2>&1
@echo abcd /G: "'abcd' not recognized" errorlevel %errorlevel%
abcd /G>NUL 2>&1 && echo YES !errorlevel! || echo NO !errorlevel!
@echo abcd /G: ^|^|   changed errorlevel %errorlevel%
find /G >NUL 2>&1 && echo YES !errorlevel! || echo NO !errorlevel!
@echo find /G: ^|^| unchanged errorlevel %errorlevel%
call t.cmd 333 && echo YES !errorlevel! || echo NO !errorlevel!
type t.cmd
t.cmd 222 && echo YES !errorlevel! || echo NO !errorlevel!

输出(来自errlevels.cmd):

==>errlevels.cmd

==>(call  )
(call ) command clears errorlevel 0

==>abcd /G 1>NUL 2>&1
abcd /G: "'abcd' not recognized" errorlevel 9009

==>abcd /G  1>NUL 2>&1  && echo YES !errorlevel!   || echo NO !errorlevel!
NO 1
abcd /G: ||   changed errorlevel 1

==>find /G   1>NUL 2>&1  && echo YES !errorlevel!   || echo NO !errorlevel!
NO 2
find /G: || unchanged errorlevel 2

==>call t.cmd 333   && echo YES !errorlevel!   || echo NO !errorlevel!
NO 333

==>type t.cmd
@exit /B %~1

==>t.cmd 222   && echo YES !errorlevel!   || echo NO !errorlevel!
YES 222

==>

注意

  • || 显示错误级别 1,尽管 'abcd' not recognized 错误应该是 9009
  • ||FIND: Invalid switch 错误保持错误级别 2 不变。
  • || 分支在 call t.cmd 333 中计算
  • && 分支在 t.cmd 222 中计算。

(调用) 上参见 DBenham's answer :

If you want to force the errorlevel to 0, then you can use this totally non-intuitive, but very effective syntax: (call ). The space after call is critical.

If you want to set the errorlevel to 1, you can use (call). It is critical that there not be any space after call.

关于windows - 命令脚本退出代码未被同一行 && 或 || 看到?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31173772/

有关windows - 命令脚本退出代码未被同一行 && 或 || 看到?的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  3. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  4. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  5. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  6. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  7. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  8. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  10. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

随机推荐