在 Windows 环境中,如果从不同的 CMD 环境调用,用于处理管道输出的可执行程序是否保证是唯一的任务?
例如,假设 script1.cmd 包含此行:
echo "some logging information" | my_pipe_program >> logfile1.txt
另外,script2.cmd 包含以下行:
echo "some other information" | my_pipe_program >> logfile2.txt
如果 script1 和 script2 恰好同时运行,Windows 是否会调用 my_pipe_program.exe 的单独实例?
我偶尔会遇到错误,命令脚本失败,错误信息为“进程无法访问文件,因为该文件正在被另一个进程使用”。此错误总是发生在通过 my_pipe_program.exe 进行管道传输的行之后。
它会导致 CMD 脚本立即停止在该位置,使 CMD 窗口保持打开状态。
冲突可能与 my_pipe_program.exe 有关,也可能与 logfile2.txt 有关。程序 my_pipe_program.exe 用于多个 CMD 文件,这些文件可能同时运行。日志文件是 CMD 文件所独有的,因此它不太可能是罪魁祸首,除非 Windows 在 CMD 文件存在后无法关闭它。有什么方法可以诊断问题并修复错误吗?
相关问题 - 有什么方法可以捕获和处理“...正在被另一个进程使用”错误并防止 CMD 文件中止?
答案1
听起来问题可能出在这里,EXE
以及它如何处理在同一台机器上同时在内存中运行的调用。启用此级别的高级日志记录以捕获详细信息或堆栈跟踪,同时模拟从同一台机器在内存中同时运行,就像问题发生时一样,这可能是最准确的答案为什么它正在这样做。
请参阅我的回答(超级用户) 前几天在 SuperUser 上,如果CMD
或BAT
文件是喜欢某个名字。
您可以结合类似这样的方法,使用这些批处理文件名检查是否有某个程序已经运行了一段时间,然后终止程序,但您必须查看其他选项,WMIC
看看是否有计时器等。如果这适用于您的情况,那么修复EXE
该级别的逻辑并捕获错误并结束可能是最好的选择,如果您在该级别进行控制的话。
其他想法
一个简单的解决方案可能是在批处理 CMD 文件启动时创建一个锁文件,以便EXE
从同一台机器启动该脚本的所有脚本首先检查锁文件是否存在,如果存在,则结束该脚本(或者可能暂停几分钟然后再次检查等)。
您可以结束脚本 [ GOTO locked
] 或暂停几秒钟,然后转到该例程 [ GOTO lockedrecheck
] 并再次检查其他进程是否已完成,如果这对您来说足够了,则删除该文件。
如果锁文件不存在,它会创建该文件,然后运行该进程,完成后删除锁文件,以便其他进程可以运行(下面的示例)。
您还可以将其添加到2<&1
日志文件的末尾以获取更多详细信息(如果EXE
允许以这种方式捕获则无法捕获)(下面的示例脚本逻辑)。
锁定文件示例(结束或暂停并重新检查)
<ABOVE LOGIC>
<ABOVE LOGIC>
<ABOVE LOGIC>
<ABOVE LOGIC>
:SetLockFile
::SET check for, and create lock file to ensure concurrent runs aren't possible
SET lockfile=\\server\share\lockfiles\my_pipe_program.lck
IF EXIST %lockfile% GOTO locked
::IF EXIST %lockfile% GOTO lockedrecheck
ECHO This file is locked until current %~nx0 script ends or finishes using the EXE >> %lockfile%
ECHO "some logging information" | my_pipe_program >> %logfile% 2<&1
<More Logic>
<More Logic>
<More Logic>
<More Logic>
:end
ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> %logfile%
ECHO End: %date% at %time% >> %logfile%
ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> %logfile%
DEL /Q /F "%lockfile%"
ENDLOCAL
GOTO EOF
:locked
:: Come here to end the script since the lock file does exist
ECHO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>> %logfile%
ECHO LOCKED FILE: %~nx0 - %date% at %time%: FILE IS IN USE AND LOCKED >> %logfile%
ECHO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>> %logfile%
ENDLOCAL
GOTO EOF
:lockedrecheck
:: Come here to Pause the script with a loopback ping to nul for 3 minutes or roughly 180 seconds
PING 127.0.0.1 -n 180 > nul
GOTO :SetLockFile
2<&1
例子
echo "some logging information" | my_pipe_program >> logfile1.txt 2<&1