抱歉,如果我是一個愚蠢的 powershell 菜鳥,但是作業顯然無法寫入終端有什么問題?我該如何解決?
# test.ps1
function myjob {
Write-Host "Hello, World!" # doesn't show
}
Start-Job -Name MyJob -ScriptBlock ${function:myjob}
Wait-Job MyJob
Remove-Job MyJob
uj5u.com熱心網友回復:
聽起來您正試圖Write-Host從后臺作業直接、同步地寫入控制臺(終端)。
但是,PowerShell作業不允許直接訪問呼叫者的控制臺。 任何輸出 - 甚至到 PowerShell主機(如果在一個控制臺中運行,它在前臺使用的是控制臺)都通過 PowerShell 的輸出流系統進行路由(請參閱概念about_Redirection幫助主題)。
因此,您始終需要Receive-Jobcmdlet 才能接收PowerShell 作業的輸出。
下面的例子同步接收作業輸出,即阻塞執行,直到作業完成(-Wait),然后將其洗掉(-AutoRemoveJob);請參閱底部的異步(輪詢,非阻塞)方法。
$null = Start-Job -Name MyJob -ScriptBlock { Write-Host "Hello, World!" }
Receive-Job -Wait -AutoRemoveJob -Name MyJob
Write-Host警告在作業中重復使用:
在前臺使用中,
Write-Host輸出——即使主要設計用于發送到主機(控制臺)——也可以通過資訊流(其編號為6,在 PSv5 中可用)重定向或捕獲;例如:# OK - no output Write-Host 'silence me' 6>$nullWrite-Host但是,從 PowerShell 7.2.1 開始,無法重定向或捕獲通過(基于子行程的)后臺作業接收的輸出:# !! `silence me` still prints. Start-Job { Write-Host 'silence me' } | Receive-Job -Wait -AutoRemoveJob 6>$null相比之下,當使用(通常更可取的)基于執行緒的后臺作業(與基于子行程的后臺作業相反)時,可以通過以下方式重定向/捕獲它:
Start-ThreadJob# OK - no output Start-ThreadJob { Write-Host 'silence me' } | Receive-Job -Wait -AutoRemoveJob 6>$null
等待作業以非阻塞方式完成,并在作業輸出可用時傳遞:
# Start a simple job that writes a "." to the host once a second,
# for 5 seconds
$job = Start-Job $job -ScriptBlock {
1..5| ForEach-Object { Write-Host -NoNewLine .; Start-Sleep 1 }
}
"Waiting for job $($job.Id) to terminate while passing its output through..."
do {
$job | Receive-Job # See if job output is available (non-blocking) and pass it through
Start-Sleep 1 # Do other things or sleep a little.
} while (($job | Get-Job).State -in 'NotStarted', 'Running')
"`nJob terminated with state '$($job.State)'."
$job | Remove-Job # Clean up.
注意:在這個簡單的情況下,預期的終止狀態是
Completed(沒有發生或僅發生非終止錯誤)或Failed(生成了腳本終止錯誤throw(并且未在作業中捕獲))。- 有關可能狀態的完整串列,請參閱
[System.Management.Automation.JobState]列舉。
- 有關可能狀態的完整串列,請參閱
回傳的作業物件
Start-Job- 而不是通過引數自行選擇的名稱-Name- 用于與作業互動。這消除了給定的可能存在多個作業的歧義-Name,所有這些作業都將成為目標。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/414562.html
標籤:
