linux PowerShell 中“nohup"的等价物是什么? [英] What is the equivalent of 'nohup' in linux PowerShell?
问题描述
我非常清楚重复问题的存在.但该问题已标记为已回答,我认为它根本无法回答原始问题.
$ nohup command
即使 nohup 的父进程(shell)死亡,它也会继续执行命令.更多信息请见:nohup 和ampersand 的区别是什么..>
对于 Win32 api,我看到了 当系统终止一个进程时,它不会终止该进程创建的任何子进程.终止进程不会为 WH_CBT 挂钩程序生成通知..这是我要问的理想行为.这可以自动与 win32 powershell 配合使用.但是对于 linux powershell 的 Start-Job
,它只是 powershell 上下文中的后台作业,因为它会在 powershell 被杀死时被杀死.
示例:
➜ ~ powershell-preview -c "Start-Job {/bin/sleep 1000 }";ID 名称 PSJobTypeName 状态 HasMoreData 位置命令-- -- ------------- ----- ----------- -------- -------1 Job1 BackgroundJob 运行 True localhost/bin/sleep 1000➜ ~ ps ux |睡觉mvaidya 166986 0.0 0.0 9032 664 pts/11 S+ 18:59 0:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox sleep
使用 Start-Job
或 PowerShell v6+ 的 &
后台操作员 不是一个选项,因为终止作业也会终止子进程从它启动,哪些作业是 - 在 Windows 和类 Unix 平台上.
但是,您可以通过 Start-Process
cmdlet:
在Unix类平台上,您可以将Start-Process
与nohup
结合起来:
以下示例启动了一个后台 PowerShell 实例,即使在您关闭启动终端后该实例仍保持活动状态;它每秒发出一个 .
,并且 nohup
在当前目录的文件 nohup.out
中收集 stdout 和 stderr 输出,附加到这样的如果文件已经存在:
# 运行 2 分钟并将 stdout 和 stderr 输出附加到 ./nohup.out启动进程 nohup 'pwsh -nop -c "1..120 |% { 写主机 .- 换行;睡眠 1 }"'
警告:从 PowerShell 7.2 开始,通过 SSH 连接运行此命令仅当连接通过 ssh<启动时才有效/code>
,而不是通过 PowerShell 自己的基于 SSH 的远程 cmdlet,例如 Invoke-Command
和 Enter-PSSession
[1].
例如 - 假设用户在目标计算机上的默认 shell 是 pwsh
(PowerShell),可以使用以下命令;请注意,选项 -t
是必需的 以分配伪终端 (pty),以便 nohup
认为其 stdout 已连接到终端因此将其输出发送到文件 .\nohup.out
):
ssh -t @'启动进程 nohup ''pwsh -nop -c \"1..120 |% { 写主机 .- 换行;睡眠 1 }\"'''
注意对 \"
而不仅仅是 "
的惊人需求,需要补偿 PowerShell 至今仍损坏的参数传递给外部程序PowerShell 7.1 - 请参阅此答案.
相比之下,如果用户在目标计算机上的默认 shell 是 POSIX-compatible shell,例如 bash
,请使用以下 (从 PowerShell 运行):
# 重要提示:如果目标机器运行的是 macOS 而不是 Linux,请使用# `pwsh` 的*完整路径*,默认为 `/usr/local/bin/pwsh`.ssh -t <用户>@<主机>'nohup pwsh -nop -c ''1..120 |% { 写主机 .- 换行;睡眠 1 }'' &whoami >/dev/null'
注意在提交后台作业( &
)后使用虚拟命令whoami >/dev/null
,这似乎是为了确保nohup
有足够的时间来实际启动它的目标命令.
在 Windows 上,Start-Process
默认在新的控制台窗口中创建一个独立的进程,您可以使用 -WindowStyle Hidden
在隐藏窗口中启动该进程,该窗口将独立于启动外壳而保持活动状态.
# 运行 2 分钟并将成功输出附加到 ./nohup.out启动进程 -WindowStyle 隐藏 pwsh '-nop -c "1..120 |% { 添加内容 -nonewline nohup.out -Value .;睡眠 1 }"'
警告:这不能原样远程:
在远程会话中,
Start-Process
无法以这种方式在单独的(隐藏)窗口中启动进程,因此 在退出远程会话时,启动的进程将终止为好吧.但是,您可以创建一个断开连接会话,该会话在目标计算机上保持活动状态,直到它被明确删除(或直到目标计算机重新启动);或者,显式创建一个常规(已连接)会话并在需要时保留它 - 尽管如果调用计算机在任务完成之前重新启动,任务将再次终止(除非您先明确断开会话).
一个例子,使用Invoke-Command
的 -InDisconnectedSession
开关:
# 在断开连接的会话中远程启动命令,然后# 返回一个会话信息对象:$disconnSess = Invoke-Command -Computer -InDisconnectedSession {启动进程 -WindowStyle 隐藏 pwsh '-nop -c "1..120 |% { 添加内容 -nonewline nohup.out -Value .;睡眠 1 }"'}# ...让命令完成# 再次删除会话删除-PSSession $disconnSess
[1] 这些 cmdlet 不分配伪终端 (pty),缺少它会导致 nohup
将其输出打印到 stdout 和 stderr 而不是文件 .\nohup.out
.此外,这种意外的、直接打印的输出可能会导致远程 PowerShell 会话崩溃.
I very well know existence of duplicate question. But that question is marked answered and I don't think it at all answers the original question.
The $ nohup command
keeps executing command even if the parent process (shell) of nohup dies. More info here: What's the difference between nohup and ampersand.
In case of Win32 api, I see line When the system is terminating a process, it does not terminate any child processes that the process has created. Terminating a process does not generate notifications for WH_CBT hook procedures.. This is the desired behaviour I am asking about. This works with win32 powershell automatically. But with linux powershell's Start-Job
it's merely background job in the powershell context in the sense that it gets killed when powershell gets killed.
Example:
➜ ~ powershell-preview -c "Start-Job { /bin/sleep 1000 }"
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 Job1 BackgroundJob Running True localhost /bin/sleep 1000
➜ ~ ps ux | grep sleep
mvaidya 166986 0.0 0.0 9032 664 pts/11 S+ 18:59 0:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox sleep
Using Start-Job
or PowerShell v6+'s &
background operator isn't an option, because terminating the job will also terminate child processes launched from it, which jobs are - both on Windows and on Unix-like platforms.
However, you can achieve nohup
-like behavior via the Start-Process
cmdlet:
On Unix-like platforms, you can combine Start-Process
with nohup
:
The following example launches a background PowerShell instance that stays alive even after you close the launching terminal; it emits a .
every second, and nohup
collects both stdout and stderr output in file nohup.out
in the current directory, appending to such a file if it already exists:
# 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 }"'
Caveat: As of PowerShell 7.2, running this command via a SSH connection only works if the connection was initiated via ssh
, not via PowerShell's own SSH-based remoting cmdlets, such as Invoke-Command
and Enter-PSSession
[1].
For instance - assuming that the user's default shell on the target computer is pwsh
(PowerShell), the following command could be used; note that option -t
is needed in order to allocate a pseudo terminal (pty), so that nohup
thinks its stdout is connected to a terminal and therefore sends its output to file .\nohup.out
):
ssh -t <user>@<host> 'Start-Process nohup ''pwsh -nop -c \"1..120 | % { write-host . -nonewline; sleep 1 }\"'''
Note the surprising need for \"
rather than just "
, required to compensate for PowerShell's still-broken argument-passing to external programs as of PowerShell 7.1 - see this answer.
By contrast, if the user's default shell on the target computer is a POSIX-compatible shell such as bash
, use the following (run from 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'
Note the use of dummy command whoami >/dev/null
after submitting the background job ( &
), which is seemingly required to ensure that nohup
gets enough time to actually launch its target command.
On Windows, where Start-Process
by default creates an independent process in a new console window, you can use -WindowStyle Hidden
to launch that process in a hidden window that will remain alive independently of the launching 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 }"'
Caveat: This does not work as-is work remoting:
In a remoting sessio,
Start-Process
cannot launch the process in a separate (hidden) window this way, so on exiting the remoting session the launched process is terminated as well.However, you can create a disconnected session that remains alive on the target computer until it is explicitly deleted (or until the target computer reboots); alternatively, create a regular (connected) session explicitly and keep it as long as needed - though if the calling computer reboots before the task is completed, the task is again terminated (unless you explicitly disconnect the session first).
An example, using Invoke-Command
's -InDisconnectedSession
switch:
# 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] These cmdlets do not allocate a pseudo terminal (pty), the absence of which causes nohup
to print its output to stdout and stderr rather than to file .\nohup.out
. Additionally, this unexpected, directly printed output can cause the remote PowerShell session to crash.
这篇关于linux PowerShell 中“nohup"的等价物是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!