我需要在运行批处理文件的 powershell 代码中设置超时,以防批处理文件运行较长时间或卡住。我在批处理脚本中也有一个超时
timeout 300> nul
,从中我似乎收到了此错误,它只是跳过超时并执行下一行。如果我从批处理脚本中删除超时,则不会收到此错误。但我在两个地方都需要超时,我该如何解决这个问题?
错误 - 错误:不支持输入重定向,立即退出进程。
PS 代码-
$bs={
cd D:\files\
cmd.exe /c "mybatchfile.bat"
}
$timeoutseconds=800
$j=Start-Job -Scriptblock $bs
if(wait-Job $j -Timeout $timeoutseconds) {Receive-Job $j}
Remove-Job -force $j
批处理脚本是这样的
cmd1
cmd2
timeout 300> nul
cmd3
您可能有兴趣以另一种方式添加延迟。另一种选择是等待:
REM # waits a delay before refresh status of service
ping localhost
事实上,在远程服务器上使用 GitLab 代理安装脚本的场景中,我也遇到了类似的远程 PowerShell 问题。通过将
timeout
替换为 ping
,脚本将不再出现错误。
每当
timeout.exe
检测到其标准输入被重定向(未附加到控制台)时,它就会中止并显示您看到的错误消息。
Start-Job
启动的后台作业的实现方式,您从作业脚本块运行的任何外部进程总是将 stdin 视为重定向,因此您将无法调用 timeout.exe
。[1]
您最好的选择是使用基于线程的后台作业,这样就不会出现此问题:
Start-ThreadJob
在单独的线程中运行脚本块在同一进程中,并且不涉及stdin重定向;此外,由于不必启动新的 PowerShell(子)进程,因此线程作业的创建速度更快,并且需要的资源更少。
Start-ThreadJob
是 ThreadJob
模块的一部分,随 PowerShell(核心)7+一起提供,并且可以在 Windows PowerShell 中按需安装(例如,使用 Install-Module -Scope CurrentUser ThreadJob
)
由于
Start-ThreadJob
还与 PowerShell 的作业管理基础架构集成,并与 Start-Job
共享核心参数语法,因此只需在代码中将 Start-Job
替换为 Start-ThreadJob
即可。
[1] 除非有办法在
timeout.exe
调用中将标准输入重新连接到控制台 - 但是,我不知道有这样的功能(<CON
会创建 Access denied
错误)。