- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我遇到了一种奇怪的情况,我编写的批处理文件报告了不正确的退出状态。这是重现问题的最小示例:
bug.cmd
echo before
if "" == "" (
echo first if
exit /b 1
if "" == "" (
echo second if
)
)
echo after
如果我运行这个脚本(使用 Python 但问题实际上也发生在以其他方式启动时),这是我得到的:
python -c "from subprocess import Popen as po; print 'exit status: %d' % po(['bug.cmd']).wait()"
echo before
before
if "" == "" (
echo first if
exit /b 1
if "" == "" (echo second if )
)
first if
exit status: 0
请注意 exit status
如何报告为 0
,即使 exit/b 1
应该使它成为 1
.
现在奇怪的是,如果我删除里面的 if
子句(这应该无关紧要,因为无论如何都不应该执行 exit/b 1
之后的所有内容)并尝试启动它:
ok.cmd
echo before
if "" == "" (
echo first if
exit /b 1
)
echo after
我再次启动它:
python -c "from subprocess import Popen as po; print 'exit status: %d' % po(['ok.cmd']).wait()"
echo before
before
(environment) F:\pf\mm_3.0.1\RendezVous\Services\Matchmaking>if "" == "" (
echo first if
exit /b 1
)
first if
exit status: 1
现在 exit status
被正确报告为 1
。
我不知道是什么原因造成的。嵌套 if
语句是否违法?
如何批量正确可靠地指示我的脚本退出状态?
注意:调用 exit 1
(没有 /b
)不是一个选项,因为它会杀死整个解释器并阻止本地脚本的使用。
最佳答案
正如@dbenham 指出的那样,“[i]如果在同一命令 block 中 EXIT/B
之后解析命令,那么问题就会显现,即使后续命令永远不会执行”。在这种特殊情况下,IF
语句的主体基本上被评估为
(echo first if) & (exit /b 1) & (if "" == "" (echo second if))
其中 &
运算符是函数 cmd!eComSep
(即命令分隔符)。 EXIT/B 1
命令(函数 cmd!eExit
)通过将全局变量 cmd!LastRetCode
设置为 1 来评估,然后基本上执行 转到:EOF
。当它返回时,第二个 eComSep
看到 cmd!GotoFlag
已设置,因此跳过评估右侧。在这种情况下,它还会忽略左侧的返回码,而是返回 SUCCESS
(0)。这会向上传递到堆栈,成为进程退出代码。
下面我包含了运行 bug.cmd 和 ok.cmd 的调试 session 。
错误命令:
(test) C:\Temp>cdb -oxi ld python
Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
CommandLine: python
Symbol search path is: symsrv*symsrv.dll*
C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
(1404.10b4): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00000000`77848700 cc int 3
0:000> g
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40)
[MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from subprocess import Popen as po
>>> po('bug.cmd').wait()
Symbol search path is: symsrv*symsrv.dll*
C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
(1818.1a90): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00000000`77848700 cc int 3
1:005> bp cmd!eExit
1:005> g
(test) C:\Temp>echo before
before
(test) C:\Temp>if "" == "" (
echo first if
exit /b 1
if "" == "" (echo second if )
)
first if
Breakpoint 0 hit
cmd!eExit:
00000000`4a6e8288 48895c2410 mov qword ptr [rsp+10h],rbx
ss:00000000`002fed78=0000000000000000
1:005> kc
Call Site
cmd!eExit
cmd!FindFixAndRun
cmd!Dispatch
cmd!eComSep
cmd!Dispatch
cmd!eComSep
cmd!Dispatch
cmd!Dispatch
cmd!eIf
cmd!Dispatch
cmd!BatLoop
cmd!BatProc
cmd!ECWork
cmd!ExtCom
cmd!FindFixAndRun
cmd!Dispatch
cmd!main
cmd!LUAGetUserType
kernel32!BaseThreadInitThunk
ntdll!RtlUserThreadStart
1:005> db cmd!GotoFlag l1
00000000`4a70e0c9 00 .
1:005> pt
cmd!eExit+0xe1:
00000000`4a6e8371 c3 ret
1:005> r rax
rax=0000000000000001
1:005> dd cmd!LastRetCode l1
00000000`4a70e188 00000001
1:005> db cmd!GotoFlag l1
00000000`4a70e0c9 01 .
1:005> gu;gu;gu
cmd!eComSep+0x14:
00000000`4a6e6218 803daa7e020000 cmp byte ptr [cmd!GotoFlag
(00000000`4a70e0c9)],0
ds:00000000`4a70e0c9=01
1:005> p
cmd!eComSep+0x1b:
00000000`4a6e621f 0f85bd4d0100 jne cmd!eComSep+0x1d
(00000000`4a6fafe2) [br=1]
1:005>
cmd!eComSep+0x1d:
00000000`4a6fafe2 33c0 xor eax,eax
1:005> pt
cmd!eComSep+0x31:
00000000`4a6e6235 c3 ret
1:005> r rax
rax=0000000000000000
1:005> bp ntdll!RtlExitUserProcess
1:005> g
Breakpoint 1 hit
ntdll!RtlExitUserProcess:
00000000`777c3830 48895c2408 mov qword ptr [rsp+8],rbx
ss:00000000`0029f6b0=00000000003e5638
1:005> r rcx
rcx=0000000000000000
1:005> g
ntdll!ZwTerminateProcess+0xa:
00000000`777ede7a c3 ret
1:005> g
0
ok.cmd:
>>> po('ok.cmd').wait()
Symbol search path is: symsrv*symsrv.dll*
C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
(ce4.b94): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00000000`77848700 cc int 3
1:002> bp cmd!eExit
1:002> g
(test) C:\Temp>echo before
before
(test) C:\Temp>if "" == "" (
echo first if
exit /b 1
)
first if
Breakpoint 0 hit
cmd!eExit:
00000000`4a6e8288 48895c2410 mov qword ptr [rsp+10h],rbx
ss:00000000`0015e808=0000000000000000
1:002> kc
Call Site
cmd!eExit
cmd!FindFixAndRun
cmd!Dispatch
cmd!eComSep
cmd!Dispatch
cmd!Dispatch
cmd!eIf
cmd!Dispatch
cmd!BatLoop
cmd!BatProc
cmd!ECWork
cmd!ExtCom
cmd!FindFixAndRun
cmd!Dispatch
cmd!main
cmd!LUAGetUserType
kernel32!BaseThreadInitThunk
ntdll!RtlUserThreadStart
1:002> gu;gu;gu
cmd!eComSep+0x2c:
00000000`4a6e6230 4883c420 add rsp,20h
1:002> p
cmd!eComSep+0x30:
00000000`4a6e6234 5b pop rbx
1:002> p
cmd!eComSep+0x31:
00000000`4a6e6235 c3 ret
1:002> r rax
rax=0000000000000001
1:002> bp ntdll!RtlExitUserProcess
1:002> g
Breakpoint 1 hit
ntdll!RtlExitUserProcess:
00000000`777c3830 48895c2408 mov qword ptr [rsp+8],rbx
ss:00000000`0015f750=00000000002b5638
1:002> r rcx
rcx=0000000000000001
1:002> g
ntdll!ZwTerminateProcess+0xa:
00000000`777ede7a c3 ret
1:002> g
1
在 ok.cmd 的情况下,cmd!eComSep
仅在堆栈跟踪中出现一次。 exit/b 1
命令被评估为右侧操作数,因此查看 GotoFlag
的代码永远不会运行。取而代之的是,返回代码 1 向上传递到堆栈,成为进程退出代码。
关于python - 如何正确批量上报退出状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30714985/
这个问题已经有答案了: How to do case insensitive string comparison? (23 个回答) 已关闭 3 年前。 用户在我的输入栏中写入“足球”,然后执行第 6
啊,不习惯 javascript 中的字符串。 character_id= + id + correct= + correctOrIncorrect 这就是我需要制作成字符串的内容。如果您无法猜测字符
$(function() { var base_price = 0; CalculatePrice(); $(".math1").on('change', function(e) { Calc
我找不到任何文章回答问题:将Spinnaker部署到Spinnaker将管理的同一Kubernetes集群是否安全/正确?我主要是指生产,HA部署。 最佳答案 我认为Spinnaker和Kuberne
我正在使用MSVC在Windows上从源代码(官方源代码发布,而不是从仓库中)构建Qt5(Qt 5.15.0)。 我正在设置环境。变量,依赖项等,然后运行具有1600万个选项的configure,最后
我需要打印一个包含重复单词的数组。我的数组已经可以工作,但我不知道如何正确计算单词数。我已经知道,当我的索引计数器 (i) 为 49 时,并且当 (i) 想要计数到 50 时,我会收到错误,但我不知道
我正在遵循一个指南,该指南允许 Google map 屏幕根据屏幕尺寸禁用滚动。我唯一挣扎的部分是编写一个代码,当我手动调整屏幕大小时动态更改 True/False 值。 这是我按照说明操作的网站,但
我有一个类“FileButton”。它的目的是将文件链接到 JButton,FileButton 继承自 JButton。子类继承自此以使用链接到按钮的文件做有用的事情。 JingleCardButt
我的 friend 数组只返回一个数字而不是所有数字。 ($myfriends = 3) 应该是…… ($myfriends = 3 5 7 8 9 12). 如果我让它进入 while 循环……整个
这个问题在这里已经有了答案: Is there a workaround to make CSS classes with names that start with numbers valid?
我正在制作一个 JavaScript 函数,当调整窗口大小时,它会自动将 div 的大小调整为与窗口相同的宽度/高度。 该功能非常基本,但我注意到在调整窗口大小时出现明显的“绘制”滞后。在 JS fi
此问题的基本视觉效果可在 http://sevenx.de/demo/bootstrap-carousel/inc.carousel/tabbed-slider.html 获得。 - 如果你想看一看。
我明白,如果我想从函数返回一个字符串文字或一个数组,我应该将其声明为静态的,这样当被调用的函数被返回时,内容就不会“消亡”。 但我的问题是,当我在函数内部使用 malloc 分配内存时会怎样? 在下面
在 mySQL 数据库中存储 true/false/1/0 值最合适(读取数据消耗最少)的数据字段是什么? 我以前使用过一个字符长的 tinyint,但我不确定它是否是最佳解决方案? 谢谢! 最佳答案
我想一次读取并处理CSV文件第一行中的条目(例如打印)。我假设使用Unix风格的\n换行符,没有条目长度超过255个字符,并且(现在)在EOF之前有一个换行符。这意味着它是fgets()后跟strto
所以,我们都知道 -1 > 2u == true 的 C/C++ 有符号/无符号比较规则,并且我有一种情况,我想有效地实现“正确”比较。 我的问题是,考虑到人们熟悉的尽可能多的架构,哪种方法更有效。显
**摘要:**文章的标题看似自相矛盾。 本文分享自华为云社区《Java异常处理:如何写出“正确”但被编译器认为有语法错误的程序》,作者: Jerry Wang 。 文章的标题看似自相矛盾,然而我在“正
我有一个数据框,看起来像: dataDemo % mutate_each(funs(ifelse(. == '.', REF, as.character(.))), -POS) # POS REF
有人可以帮助我使用 VBScript 重新格式化/正确格式化带分隔符的文本文件吗? 我有一个文本文件 ^分界如下: AGREE^NAME^ADD1^ADD2^ADD3^ADD4^PCODE^BAL^A
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我是一名优秀的程序员,十分优秀!