#后台作业
后台作业(job)让命令在后台运行,当前会话可以继续执行其他操作。作业适合耗时较长、无需立即拿到结果的任务,例如批量复制文件或查询多台主机。
#创建作业
Start-Job 使用脚本块创建作业:
> $job = Start-Job -ScriptBlock {
Get-Process | Sort-Object CPU -Descending | Select-Object -First 3
}
也可以用 -FilePath 运行脚本文件。需要向脚本块传参时使用 -ArgumentList,并在脚本块中通过 $args 或 param() 接收:
> $job = Start-Job -ScriptBlock {
param($path)
Get-ChildItem -Path $path
} -ArgumentList '/tmp'
#查看与接收结果
Get-Job 列出当前会话中的作业及其状态:
> Get-Job
Receive-Job 获取作业产生的输出:
> Receive-Job -Id 1
> Receive-Job -Job $job -Keep
- 默认情况下,
Receive-Job读取后会把结果从作业中移除。 - 使用
-Keep可以保留结果,便于再次读取。
#等待与停止
Wait-Job 等待作业完成,可以设置超时:
> Wait-Job -Id 1
> Wait-Job -Job $job -Timeout 60
Stop-Job 停止正在运行的作业:
> Stop-Job -Id 1
Remove-Job 删除作业对象,释放资源:
> Remove-Job -Id 1
> Get-Job | Remove-Job
作业完成后不会自动从列表中消失,通常应先 Receive-Job,再 Remove-Job。
#作业与进程的区别
- 作业由 PowerShell 管理,状态包括
Running、Completed、Failed、Stopped等。 - 后台作业默认在独立的 PowerShell 子进程中运行,因此不能直接访问父会话的变量和函数。
- 作业输出在跨进程传递时会被序列化,可能丢失部分类型信息。
- 进程是操作系统的概念;作业是 PowerShell 层面的封装,一个作业通常对应一个子进程。
- 作业只存在于创建它的会话中,关闭会话后作业随之结束。
若需在父会话中访问变量,可在脚本块中使用 $using: 前缀:
> $name = 'pwsh'
> Start-Job -ScriptBlock { Get-Process -Name $using:name }
#线程作业
Start-ThreadJob 在同一个进程内用线程运行任务,启动更快、开销更小,并且可以直接共享父会话的对象:
> $job = Start-ThreadJob -ScriptBlock { 1 + 1 }
> Receive-Job -Job $job
ThreadJob 模块通常随 PowerShell 7 一起提供;若不可用,可先安装并导入该模块。线程作业不适合运行可能崩溃或需要强隔离的代码。