使用Start-Job
或 PowerShell v6+ 的&
后台运算符不是一个选项,因为终止作业也会终止从它启动的子进程,这些作业在 Windows 和类 Unix 平台上都是如此。
但是,您可以通过cmdlet实现nohup
类似行为:Start-Process
在类 Unix平台上,您可以结合Start-Process
使用nohup
:
以下示例启动一个后台 PowerShell 实例,即使您关闭启动终端,该实例仍保持活动状态;.
它每秒发出一个,并在当前目录nohup
的文件中收集 stdout 和 stderr 输出,如果它已经存在,则附加到这样的文件:nohup.out
# Runs for 2 minutes and appends both stdout and stderr output to ./nohup.out
Start-Process nohup 'pwsh -nop -c "1..120 | % { write-host . -nonewline; sleep 1 }"'
警告:从 PowerShell 7.2 开始,通过SSH连接运行此命令仅在通过启动连接时才有效ssh
,而不是通过 PowerShell 自己的基于 SSH 的远程 cmdlet,例如Invoke-Command
和[1]。Enter-PSSession
例如 -假设用户在目标计算机上的默认 shell 是pwsh
(PowerShell),可以使用以下命令;请注意,为了分配伪终端(pty),需要选项-t
nohup
,以便认为它的标准输出连接到终端,因此将其输出发送到文件.\nohup.out
):
ssh -t <user>@<host> 'Start-Process nohup ''pwsh -nop -c \"1..120 | % { write-host . -nonewline; sleep 1 }\"'''
请注意,从 PowerShell 7.1 开始,需要补偿 PowerShell 仍然损坏的参数传递给外部程序的令人惊讶的需求,\"
而不是仅仅需要 - 请参阅此答案。"
相比之下,如果用户在目标计算机上的默认 shell 是POSIX 兼容的shell,例如bash
,请使用以下命令(从 PowerShell 运行):
# IMPORTANT: If the target machine runs macOS rather than Linux, use the
# `pwsh`'s *full path*, which is `/usr/local/bin/pwsh` by default.
ssh -t <user>@<host> 'nohup pwsh -nop -c ''1..120 | % { write-host . -nonewline; sleep 1 }'' & whoami >/dev/null'
whoami >/dev/null
请注意在提交后台作业 ( ) 后使用虚拟命令 &
,这似乎是确保nohup
获得足够时间来实际启动其目标命令所必需的。
在Windows上,Start-Process
默认情况下在新的控制台窗口中创建一个独立的进程,您可以使用-WindowStyle Hidden
在隐藏窗口中启动该进程,该隐藏窗口将独立于启动 shell 保持活动状态。
# Runs for 2 minutes and appends success output to ./nohup.out
Start-Process -WindowStyle Hidden pwsh '-nop -c "1..120 | % { Add-Content -nonewline nohup.out -Value .; sleep 1 }"'
警告:这不能按原样工作远程处理:
一个例子,使用Invoke-Command
's-InDisconnectedSession
开关:
# Launch the command remotely, in a disconnected session, and
# return a session-information object:
$disconnSess = Invoke-Command -Computer <host> -InDisconnectedSession {
Start-Process -WindowStyle Hidden pwsh '-nop -c "1..120 | % { Add-Content -nonewline nohup.out -Value .; sleep 1 }"'
}
# ... Let the command finish
# Remove the session again
Remove-PSSession $disconnSess
[1] 这些 cmdlet 不分配伪终端 (pty),缺少伪终端会导致nohup
将其输出打印到 stdout 和 stderr 而不是 file .\nohup.out
。此外,这种意外的直接打印输出可能会导致远程 PowerShell 会话崩溃。