在 bash 中,与号 (&) 可用于在后台运行命令,并在命令完成运行之前将交互控制返回给用户。在 Powershell 中是否有等效的方法?
bash 中的用法示例:
sleep 30 &
在 bash 中,与号 (&) 可用于在后台运行命令,并在命令完成运行之前将交互控制返回给用户。在 Powershell 中是否有等效的方法?
bash 中的用法示例:
sleep 30 &
只要命令是可执行文件或具有关联可执行文件的文件,请使用Start-Process(可从 v2 获得):
Start-Process -NoNewWindow ping google.com
您还可以将此作为功能添加到您的个人资料中:
function bg() {Start-Process -NoNewWindow @args}
然后调用变为:
bg ping google.com
在我看来,Start-Job 对于在后台运行进程的简单用例来说是一种过度杀伤:
注意:关于您的初始示例,“bg sleep 30”将不起作用,因为 sleep 是 Powershell 命令行开关。Start-Process 仅在您实际分叉一个进程时才有效。
从 PowerShell Core 6.0 开始,您可以&
在命令结束时进行编写,这相当于在当前工作目录的后台运行您的管道。
它不等同&
于 bash,它只是当前 PowerShell作业功能的一种更好的语法。它返回一个作业对象,因此您可以使用您将用于作业的所有其他命令。例如Receive-Job
:
C:\utils> ping google.com &
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
35 Job35 BackgroundJob Running True localhost Microsoft.PowerShell.M...
C:\utils> Receive-Job 35
Pinging google.com [172.217.16.14] with 32 bytes of data:
Reply from 172.217.16.14: bytes=32 time=11ms TTL=55
Reply from 172.217.16.14: bytes=32 time=11ms TTL=55
Reply from 172.217.16.14: bytes=32 time=10ms TTL=55
Reply from 172.217.16.14: bytes=32 time=10ms TTL=55
Ping statistics for 172.217.16.14:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 10ms, Maximum = 11ms, Average = 10ms
C:\utils>
如果你想在后台执行几个语句,你可以结合&
调用运算符、{ }
脚本块和这个新的&
后台运算符,如下所示:
& { cd .\SomeDir\; .\SomeLongRunningOperation.bat; cd ..; } &
以下是来自文档页面的更多信息:
支持使用&符号 (&) 对管道进行后台处理 (#3360)
放在
&
管道的末尾会导致管道作为 PowerShell 作业运行。当管道在后台运行时,将返回一个作业对象。一旦管道作为作业运行,所有标准*-Job
cmdlet 都可用于管理作业。管道中使用的变量(忽略特定于流程的变量)会自动复制到作业中,因此Copy-Item $foo $bar &
可以正常工作。该作业也在当前目录而不是用户的主目录中运行。有关 PowerShell 作业的详细信息,请参阅about_Jobs。
来自about_operators / & 号背景运算符 &:
& 后台运算符 &
在 PowerShell 作业中运行管道之前的管道。& 号后台操作符的行为类似于 UNIX“& 号操作符”,后者以后台进程的形式运行之前的命令。& 号后台运算符构建在 PowerShell 作业之上,因此它与
Start-Job
. 以下命令包含 & 后台运算符的基本用法。Get-Process -Name pwsh &
这在功能上等同于
Start-Job
.
Start-Job -ScriptBlock {Get-Process -Name pwsh}
由于它在功能上等同于 using
Start-Job
,因此 & 号背景运算符返回一个Job
对象,就像Start-Job does
. 这意味着您可以使用Receive-Job
,Remove-Job
就像您曾经Start-Job
开始工作时一样。$job = Get-Process -Name pwsh & Receive-Job $job
输出
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName ------ ----- ----- ------ -- -- ----------- 0 0.00 221.16 25.90 6988 988 pwsh 0 0.00 140.12 29.87 14845 845 pwsh 0 0.00 85.51 0.91 19639 988 pwsh $job = Get-Process -Name pwsh & Remove-Job $job
有关 PowerShell 作业的详细信息,请参阅about_Jobs。
似乎传递给的脚本块Start-Job
未使用与命令相同的当前目录Start-Job
执行,因此请确保在需要时指定完全限定的路径。
例如:
Start-Job { C:\absolute\path\to\command.exe --afileparameter C:\absolute\path\to\file.txt }
ps2> start-job {start-sleep 20}
我还没有弄清楚如何实时获取标准输出,开始工作需要你用 get-job 轮询标准输出
更新:我无法开始工作来轻松地做我想做的事,这基本上是 bash & 运算符。到目前为止,这是我最好的 hack
PS> notepad $profile #edit init script -- added these lines
function beep { write-host `a }
function ajp { start powershell {ant java-platform|out-null;beep} } #new window, stderr only, beep when done
function acjp { start powershell {ant clean java-platform|out-null;beep} }
PS> . $profile #re-load profile script
PS> ajp
您可以使用 PowerShell 作业 cmdlet 来实现您的目标。
PowerShell 中有 6 个与作业相关的 cmdlet。
如果对此感兴趣,您可以下载示例如何在 PowerShell 中创建后台作业
你可以做这样的事情。
$a = start-process -NoNewWindow powershell {timeout 10; 'done'} -PassThru
如果你想等待它:
$a | wait-process
奖励 osx 或 linux 版本:
$a = start-process pwsh '-c',{start-sleep 5; 'done'} -PassThru
我有示例 pinger 脚本。args 作为数组传递:
$1 = start -n powershell pinger,comp001 -pa
tl;博士
Start-Process powershell { sleep 30 }
我已经在 PowerShell v1.0 中成功使用了这里描述的解决方案http://jtruher.spaces.live.com/blog/cns!7143DA6E51A2628D!130.entry 。在 PowerShell v2.0 中肯定会更容易。