向批处理/电源外壳添加超时


$fullnamexp = ((net user $winxp /domain | Select-String "Full Name") -replace "Full Name","").Trim();

如果找不到$winxp,该命令将挂起,是否有我可以使用它的超时使其在 5-10 秒后继续?不知道我会把它放在哪里。

编辑 - 我用它来拉用户名:

$reg  = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $tag1)
$key  = $reg.OpenSubKey('SOFTWAREMicrosoftWindows NTCurrentVersionWinLogon')
$winxp = $key.GetValue('DefaultUserName') -replace '^.*?\'

$winxp然后是一个登录名,例如ajstepanik然后我把它放进去:$fullnamexp = ((net user $winxp /domain | Select-String "Full Name") -replace "Full Name","").Trim();

1.21.2014 更新

 $timeoutSeconds = 5
$code = {
    ((net user $winxp /domain | Select-String "Full Name") -replace "Full Name","").Trim(); # your commands here, e.g.
}
$j = Start-Job -ScriptBlock $code
if (Wait-Job $j -Timeout $timeoutSeconds) { $fullnamexp = Receive-Job $j }
Remove-Job -force $j

虽然@mjolinor可能确实为您提供了另一种方法,但这里是对您的一般问题的直接回答:如何在 PowerShell 中强制超时?

要限制时间的任何内容包装在脚本块中,将其作为作业运行,然后使用 Wait-Job cmdlet 对操作进行时间限制。 Wait-Job将在超时期限结束时脚本块完成时返回,以发生者为准。Wait-Job返回后,您可以检查作业状态($j.state)以确定它是否中断,如果它对您很重要。

$timeoutSeconds = 5 # set your timeout value here
$j = Start-Job -ScriptBlock {
    # your commands here, e.g.
    Get-Process
    }
"job id = " + $j.id # report the job id as a diagnostic only
Wait-Job $j -Timeout $timeoutSeconds | out-null
if ($j.State -eq "Completed") { "done!" }
elseif ($j.State -eq "Running") { "interrupted" }
else { "???" }
Remove-Job -force $j #cleanup

2014.01.18 更新

这里有一个更简化的方法,还包括使用 Receive-Job 从脚本块中获取信息的实际步骤,假设你想要的东西是在 stdout 上生成的:

$timeoutSeconds = 3
$code = {
    # your commands here, e.g.
    Get-ChildItem *.cs | select name
}
$j = Start-Job -ScriptBlock $code
if (Wait-Job $j -Timeout $timeoutSeconds) { Receive-Job $j }
Remove-Job -force $j

您可以使用"开始-睡眠"暂停脚本:

Start-Sleep -s 5

net 没有明确允许您为其操作设置超时,但您可以查看有关更改套接字的 IPv4 超时的链接:

http://www.cyberciti.biz/tips/linux-increasing-or-decreasing-tcp-sockets-timeouts.html

我唯一能想象到的就是生成一个工作线程,但我什至不知道这在 bash 中是否可能,我没有足够的流畅性来回答这个问题; 此外,它还为您打开了同步问题和各种多线程问题,超出了您尝试在 bash 脚本中快速完成的问题! :P

这有帮助吗?

$query = (dsquery user -samid $winxp) 
if ($query) {$fullnamexp = ($query | dsget user -display)[1].trim()}
$fullnamexp

这个解决方案对我不起作用。 在此示例中,remove-job -force $j需要 5 秒以上。

$timeoutseconds = 1
$start = get-date
$j = start-job -scriptblock { Resolve-DnsName  1.1.1.1 }
if (wait-job $j -timeout $timeoutseconds) { $fullnamexp = receive-job $j } 
remove-job -force $j 
(get-date) - $start

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 5
Milliseconds      : 342
Ticks             : 53426422
TotalDays         : 6.18361365740741E-05
TotalHours        : 0.00148406727777778
TotalMinutes      : 0.0890440366666667
TotalSeconds      : 5.3426422
TotalMilliseconds : 5342.6422

下面是一个带有记事本的简单超时示例:

notepad
if (-not $(wait-process notepad 10; $?)) { stop-process -name notepad }
    $watchdog = 10 #seconds
    $start_time = Get-Date
    $j = Start-Job -ScriptBlock{
        #timeout command
        if ($true) {
            $i = 0
            while($true) {
                Write-Host "Count: $i"
                Start-Sleep -Milliseconds 100
                $i++
            }      
        }
        write-host "Hello"
    }
    while($true) {
        if ($j.HasMoreData) {
            Receive-Job $j
            Start-Sleep -Milliseconds 200
        }
        $current = Get-Date
        $time_span = $current - $start_time
        if ($time_span.TotalSeconds -gt $watchdog) {
            write-host "TIMEOUT!"
            Stop-Job $j
            break
        }
        if (-not $j.HasMoreData -and $j.State -ne 'Running') {
            write-host "Finished"
            break
        }
    }
    Remove-Job $j

相关内容

  • 没有找到相关文章

最新更新