在bash中,&号(&)可用于在后台运行命令,并在命令运行完成之前将交互控制返回给用户。在Powershell中是否有等效的方法来做到这一点?
在bash中的用法示例:
sleep 30 &
我已经在PowerShell v1.0中成功地使用了这里描述的解决方案http://jtruher.spaces.live.com/blog/cns!7143DA6E51A2628D!130.entry。在PowerShell v2.0中,这肯定会更容易。
ps2> start-job {start-sleep 20}
我还没有弄清楚如何实时获得stdout, start-job要求你用get-job轮询stdout
更新:我不能start-job轻松地做我想要的基本上是bash &操作符。这是我目前为止最好的一招
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
传递给Start-Job的脚本块似乎没有在与Start-Job命令相同的当前目录下执行,因此如果需要,请确保指定完全限定路径。
Start-Job
例如:
Start-Job { C:\absolute\path\to\command.exe --afileparameter C:\absolute\path\to\file.txt }
只要命令是一个可执行文件或具有关联可执行文件的文件,就使用起动过程(可从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只在实际fork一个进程时才有效。
您可以使用PowerShell作业cmdlet来实现您的目标。
在PowerShell中有6个与作业相关的cmdlet可用。
如果对它感兴趣,你可以下载如何在PowerShell中创建后台作业样例
在PowerShell Core 6.0中,你可以在命令的结尾写&,这相当于运行你的管道在当前工作目录的后台。
&
它并不等同于bash中的&,它只是当前PowerShell 工作特性的一种更好的语法。它返回一个作业对象,以便您可以使用用于作业的所有其他命令。例如Receive-Job:
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 ..; } &
以下是来自文档页面的更多信息:
从 PowerShell Core 6.0新增功能:
支持管道背景与& (&) (#3360) 将&放在管道的末尾会导致该管道作为PowerShell作业运行。当管道处于后台时,将返回一个作业对象。一旦管道作为作业运行,所有的标准*-Job cmdlet都可以用来管理作业。管道中使用的变量(忽略特定于进程的变量)会自动复制到作业中,因此Copy-Item $foo $bar &可以正常工作。作业也在当前目录而不是用户的主目录中运行。有关PowerShell作业的更多信息,请参见about_Jobs。
支持管道背景与& (&) (#3360)
将&放在管道的末尾会导致该管道作为PowerShell作业运行。当管道处于后台时,将返回一个作业对象。一旦管道作为作业运行,所有的标准*-Job cmdlet都可以用来管理作业。管道中使用的变量(忽略特定于进程的变量)会自动复制到作业中,因此Copy-Item $foo $bar &可以正常工作。作业也在当前目录而不是用户的主目录中运行。有关PowerShell作业的更多信息,请参见about_Jobs。
*-Job
Copy-Item $foo $bar &
从about_operators / & &后台操作符&:
&后台操作符& 在PowerShell作业中运行它前面的管道。&后台操作符的作用类似于UNIX的“&操作符”,后者以后台进程的形式运行之前的命令而闻名。&后台操作符构建在PowerShell作业之上,因此它与Start-Job共享许多功能。下面的命令包含&后台操作符的基本用法。 Get-Process -Name pwsh & 这在功能上等价于Start-Job的以下用法。 Start-Job -ScriptBlock {Get-Process -Name pwsh} 因为它在功能上等同于使用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。
&后台操作符&
在PowerShell作业中运行它前面的管道。&后台操作符的作用类似于UNIX的“&操作符”,后者以后台进程的形式运行之前的命令而闻名。&后台操作符构建在PowerShell作业之上,因此它与Start-Job共享许多功能。下面的命令包含&后台操作符的基本用法。
Get-Process -Name pwsh &
这在功能上等价于Start-Job的以下用法。
Start-Job -ScriptBlock {Get-Process -Name pwsh}
因为它在功能上等同于使用Start-Job,所以&后台操作符返回一个Job对象,就像Start-Job does一样。这意味着你可以使用Receive-Job和Remove-Job,就像你使用Start-Job开始作业一样。
Job
Start-Job does
Remove-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。
你可以这样做。
$a = start-process -NoNewWindow powershell {timeout 10; 'done'} -PassThru
如果你想等的话:
$a | wait-process
额外的osx或linux版本:
$a = start-process pwsh '-c',{start-sleep 5; 'done'} -PassThru
示例ping脚本我有。参数作为数组传递:
$1 = start -n powershell pinger,comp001 -pa
博士tl;
Start-Process powershell { sleep 30 }