linux PowerShell 中“nohup"的等价物是什么? [英] What is the equivalent of 'nohup' in linux PowerShell?

查看:86
本文介绍了linux PowerShell 中“nohup"的等价物是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我非常清楚重复问题的存在.但该问题已标记为已回答,我认为它根本无法回答原始问题.

$ 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-Processnohup结合起来:
以下示例启动了一个后台 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-CommandEnter-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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆