我试图了解代码中的确切位置GOTO :EOF返回?
这是代码:
SET count=1
FOR /f "tokens=*" %%G IN (somefile.txt) DO (call :subroutine "%%G")
GOTO :EOF
:subroutine
echo %count%:%1
set /a count+=1
GOTO :EOF
Run Code Online (Sandbox Code Playgroud) 在Windows批处理脚本中处理错误的常用方法是使用
if errorlevel 1 ...或等if %errorlevel% neq 0 ....通常,人们希望错误处理代码保留ERRORLEVEL.
我相信所有外部命令总是会导致ERRORLEVEL被设置为某个值,因此错误处理代码必须在执行外部命令之前在环境变量中保留ERRORLEVEL.
但内部命令怎么样?问题是,一些内部命令在成功时将ERRORLEVEL清除为0,而有些则没有.而且我找不到任何指定哪些命令做什么的文档.
所以问题是,哪些内部命令成功后将ERRORLEVEL清除为0?这不是关于返回的ERRORLEVEL代码的一般问题,而是严格关于成功结果的问题.
有些帖子如何将ERRORLEVEL重置为零的最简单方法是什么?和Windows批处理文件:.bat vs .cmd?给出部分答案.但我从未见过全面的清单.
注意: 多年来我一直很好奇.所以我最终决定进行一系列实验并得出一个明确的答案.我发布此问答来分享我发现的内容.
我试着理解批处理文件中单个命令行中的多个命令是如何工作的.
dir & md folder1 & rename folder1 mainfolder
Run Code Online (Sandbox Code Playgroud)
和其他情况类似的命令,但&用&&.
dir && md folder1 && rename folder1 mainfolder
Run Code Online (Sandbox Code Playgroud)
1.这两种情况有什么区别?
我想问的其他事情:
单线batch.bat:
dir & md folder1 & rename folder1 mainfolder
Run Code Online (Sandbox Code Playgroud)
多线程batch.bat:
dir
md folder1
rename folder1 mainfolder
Run Code Online (Sandbox Code Playgroud)
2.这种单线程和多线程在批处理文件程序方面是否相同?
还有一件事我想知道:
3.如果我从main.bat调用其他批处理文件,它们是否独立运行?主批处理文件不等待其他批处理文件中的结束程序?怎么做?
考虑以下bat,test.bat(PC01关闭):
mkdir \\PC01\\c$\Test || goto :eof
Run Code Online (Sandbox Code Playgroud)
如果我从命令shell运行该bat:
> test.bat || echo 99
> if ERRORLEVEL 1 echo 55
Run Code Online (Sandbox Code Playgroud)
输出只有55.没有99.有一个错误级别,但||操作员没有看到它.
如果我用那个蝙蝠跑 cmd /c -
> cmd /c test.bat || echo 99
> if ERRORLEVEL 1 echo 55
Run Code Online (Sandbox Code Playgroud)
输出为空白.Errorlevel为0.
如果我删除了|| goto :eof,一切都按照人们的预测 - 即输出即可
99 55
有谁知道为什么这种半生半熟的ERRORLEVEL行为正在发生?
在重定向失败时(由于文件不存在或文件访问不足),ErrorLevel似乎没有设置该值(在以下示例中,文件test.tmp是写保护的,文件test.nil不存在):
>>> (call ) & rem // (reset `ErrorLevel`)
>>> > "test.tmp" echo Text
Access is denied.
>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=0
>>> (call ) & rem // (reset `ErrorLevel`)
>>> < "test.nil" set /P DUMMY=""
The system cannot find the file specified.
>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=0
Run Code Online (Sandbox Code Playgroud)
但是,只要失败的重定向后面跟着||查询退出代码的条件连接运算符,ErrorLevel就会1意外地设置为:
>>> (call ) & rem // (reset `ErrorLevel`)
>>> (> "test.tmp" echo Text) || echo Fail
Access is denied.
Fail
>>> …Run Code Online (Sandbox Code Playgroud) 我正在批处理文件中运行 SQL 请求,我需要获取错误级别及其给出的输出。我尝试过使用:
for /f "tokens=*" %%i in ('%SQLCommand%') do ( ...
Run Code Online (Sandbox Code Playgroud)
在“do”中,如果错误级别为1,那么我可以执行我计划执行的任何操作,但我似乎无法找到从命令结果中获取错误级别的方法。我也不确定错误级别是否可以在循环中更改,但我计划对其进行测试,以便我可以了解命令是否更改错误级别。
我正在阅读一篇关于ss64关于命令提示符中的环境变量的文章。
本文后面有一个表,其中列出了命令提示符中常见的环境变量。其中列出的一些变量被称为易失性(只读)。文章中的一句话指出:-
动态环境变量是只读的,并且每次扩展变量时都会进行计算。当所有变量都用 SET 列出时,这些变量将不会出现在列表中。不要尝试直接设置动态变量。
后两句话我明白了。但我无法理解第一个。
疑问:-
%userprofile%是非易失性变量,解析为%SystemDrive%\Users\{username},%homepath%是易失性变量,解析为Users\{Username}。这两个命令非常相似(除了systemdrive)。那为什么一个是易失性的,另一个是非易失性的呢?
变量动态的标准是什么?是什么使%appdata%(只是一个例子)成为非易失性变量?
每次扩展变量时都会计算动态变量,这对于诸如此类的变量是有意义的,%CD% %DATE% %TIME% %RANDOM%因为如果它们是非易失性的,它们就会失去其功能。但效果如何呢%homepath%?
一些非易失性变量中含有某种动态成分。前任。%userprofile%有%SystemDrive%并且{username}在它的路径中。那么这些变量怎么不是动态的呢?
我认为我对ERRORLEVEL与%ERRORLEVEL%有基本的了解,但是!ERRORLEVEL!使我困惑。
我正在制作一个脚本,该脚本调用可执行文件,然后任务列表以查看其是否正在运行,然后通过taskkill将其杀死,然后尝试输出错误级别并针对其他exe重复此操作,而我意识到我真的不明白批处理中的错误级别。
我将变量设置为!errorlevel!然后在回显中使用不带引号的变量,并且在设置后出现错误时,变量从一个uint16更改为另一个uint16,例如它引用了真实的变量而不是副本。我要复制。有人可以解释这些家伙之间的区别吗?
更新:这是我正在处理的代码段。
for %%P in (%executableList%) do (
echo ----------------------------------------------------------------------------------
set exeErrorlevel=0
set running=false
start %%~fP
set exeErrorlevel=!ERRORLEVEL!
rem for debugging purposes
echo %%~nP%%~xP older errorlevel %ERRORLEVEL%
echo %%~nP%%~xP newer errorlevel !ERRORLEVEL!
echo before tasklist running var is : !running!
tasklist /FI "IMAGENAME eq %%~fP" | find /I /N /C "%%~fP" >nul && set running=true
echo after tasklist is running var is: !running!
if !running! equ true (
echo %%~nP%%~xP Program is running
taskkill /F /IM %%~nP%%~xP /T …Run Code Online (Sandbox Code Playgroud) 我试图运行批处理文件,start /high仍然得到返回/退出代码,即%ERRORLEVEL%.问题似乎是命令START不返回批处理文件返回的退出代码.
我们有一个简单的批处理文件用于测试命名BatFileThatReturnsOne.bat.
内容BatFileThatReturnsOne.bat是
EXIT /B 1
Run Code Online (Sandbox Code Playgroud)
我们这样称呼:
start /high /wait BatFileThatReturnsOne.bat
Run Code Online (Sandbox Code Playgroud)
但无论批处理文件返回什么,执行start永远不会有%ERRORLEVEL%0(零)以外的任何东西.
这实际上是由CloudFormation中的cfn-init调用的,但这可能不相关,因为我们可以从命令行窗口重现它.
实际的电话是:
cmd.exe /C start /high /wait BatFileThatReturnsOne.bat
Run Code Online (Sandbox Code Playgroud)
如何将start其设置为%ERRORLEVEL%0(零)以外的其他值?
pushd有没有办法在脚本末尾撤消所有内容。我所拥有的是:
pushd somwhere
rem doing stuff
goto end
:end
popd
goto :EOF
Run Code Online (Sandbox Code Playgroud)
我想要的是:
setlocal
pushd somwhere
rem doing stuff
goto :EOF
Run Code Online (Sandbox Code Playgroud)
但这不起作用,目录保持“pushd”状态。我无法说出pushd会发生多少次的另一种尝试是:
set CurrentDir=%CD%
rem doing a lot of pushd and popd
pushd somwhere
:POPBACK
if /i not "%CD%" == "%CurrentDir%" popd & goto POPBACK
Run Code Online (Sandbox Code Playgroud)
但这看起来我很容易陷入困境:POPBACK。添加一个计数器来退出该循环有点不确定我最终会在哪个目录。
在这种情况下,我想知道 a 是否可以看到 Pushd 目录的堆栈。我发现的唯一的事情是$+为prompt $P$+$G每个 Pushd 目录添加一个“+”,例如D:\CMD++>。但我看不出如何利用它。
编辑:我刚刚注意到有一些问题让$+我prompt困惑。上面示例setlocal中的实际上使脚本返回到初始目录,但提示符显示一个“+”,表示缺少popd.
D:\CMD>test.cmd
D:\CMD>prompt $P$+$g
D:\CMD>setlocal
D:\CMD>pushd e:\DATA …Run Code Online (Sandbox Code Playgroud) 我最近有很多互联网连接停机时间.因此,我想列出每次遇到问题时将其发送给我的ISP.为了使它不那么乏味,我想,制作一种报告并将其作为日志文件发送会很好.我偶然发现了一些解决方案,但我找到的最好的解决方案是在这个网站上:用Joost Kuin的时间戳 Ping.
我已经调整了一下这个代码,但我遇到了一个问题.如果我尝试使用if not %errorlevel% 0 do (...),if %errorlevel% 1 do (...)并尝试运行.bat文件,Windows命令处理器窗口会弹出并消失.没有这个条件,批处理文件运行正常.但它没有做它的目的.我想制作2个文件,一个使用普通的ping日志,另一个只有超时和目标主机无法访问的时间戳.这是我第一次使用Windows脚本.我以前习惯用C++编写代码.我没有获得host_ip,而是获得了与外部网络的第一次连接的IP地址.
@echo off
set host=host_ip
set logfile=Ping_test.log
set logfile_fail=Ping_test_fail.log
echo Target Host = %host% >%logfile%
for /f "tokens=*" %%A in ('ping %host% -n 1') do (echo (%%A>>%logfile% && GOTO Ping)
:Ping
for /f "tokens=* skip=2" %%A in ('ping %host% -n 1 ') do (
echo %date% %time:~0,2%:%time:~3,2%:%time:~6,2% %%A>>%logfile%
if not %errolevel% 0 do (echo %date% %time:~0,2%:%time:~3,2%:%time:~6,2% errorlvel %errorlevel% %%A>>%logfile_fail%)
echo %errorlevel% …Run Code Online (Sandbox Code Playgroud) batch-file ×10
cmd ×8
windows ×6
errorlevel ×3
command-line ×1
exit-code ×1
for-loop ×1
pushd ×1
simultaneous ×1