Powershell相当于bash&符号(&)用于分叉/运行后台进程

edd*_*ves 138 powershell

在bash中,&符号(&)可用于在后台运行命令,并在命令运行完毕之前将交互式控件返回给用户.在Powershell中有没有相同的方法呢?

bash中的用法示例:

 sleep 30 &
Run Code Online (Sandbox Code Playgroud)

Bog*_*mac 115

只要命令是可执行文件或具有关联可执行文件的文件,请使用Start-Process(可从v2获得):

Start-Process -NoNewWindow ping google.com
Run Code Online (Sandbox Code Playgroud)

您也可以在配置文件中将其添加为功能:

function bg() {Start-Process -NoNewWindow @args}
Run Code Online (Sandbox Code Playgroud)

然后调用变为:

bg ping google.com
Run Code Online (Sandbox Code Playgroud)

在我看来,Start-Job对于在后台运行进程的简单用例来说太过分了:

  1. Start-Job无权访问您的现有范围(因为它在单独的会话中运行).你不能做"Start-Job {notepad $ myfile}"
  2. Start-Job不保留当前目录(因为它在单独的会话中运行).您无法执行"Start-Job {notepad myfile.txt}",其中myfile.txt位于当前目录中.
  3. 输出不会自动显示.您需要以作业的ID作为参数运行Receive-Job.

注意:关于您的初始示例,"bg sleep 30"不起作用,因为sleep是Powershell命令行开关.Start-Process仅在实际分叉进程时有效.

  • 很高兴我找到了这个答案.我正在寻找相当于Unix fork-two机制的东西.对我来说,似乎以"Start-Job"开头的东西将在PS shell退出时被杀死.相比之下,似乎以"Start-Process"开头的东西将在PS shell退出后继续运行.这是**主要的**差异. (7认同)
  • 但请注意,您无法使用“Start-Process”进行输出重定向,因此这不起作用:“Start-Process {ping -n 1000 example.com > ping__example.com.txt }”。与“Start-Job”相同的事情可以正常工作(尽管您必须使用输出文件的完整路径)。 (3认同)

hal*_*000 36

这是这个问题的几个答案.

  1. 您无法轻松地在版本1中执行此操作
  2. 版本2(现在在社区技术预览2中)确实具有此功能,它被称为Job(以前称为PSJob).在这里这里了解更多相关信息.
  3. 你实际上可以在v1中以艰难的方式去做,随意拥有它,但我从来没有打扰过.

  • 托管PowerShell进程终止后,`Start-Job`就会死掉,所以它不是一个可行的fork替换. (9认同)
  • @Marcin - 这个答案是从2008年开始的.在Windows 7中,powershell 2.0是RTM并且具有用于后台作业的"start-job"cmdlet. (4认同)
  • @marcin类型"get-command*job"你应该看到几个结果.检查帮助页面,如果有,请创建新问题. (2认同)

Gia*_*rdi 21

似乎传递给的脚本块Start-Job不是使用与Start-Job命令相同的当前目录执行的,因此请确保在需要时指定完全限定的路径.

例如:

Start-Job { C:\absolute\path\to\command.exe --afileparameter C:\absolute\path\to\file.txt }
Run Code Online (Sandbox Code Playgroud)

  • 因此,例如,如果我需要在命令行中运行Git Pull,我需要指定所有内容的完整路径......?这真的很烦人. (2认同)

Dus*_*etz 20

ps2> start-job {start-sleep 20}
Run Code Online (Sandbox Code Playgroud)

我还没弄明白如何实时获得stdout,start-job要求你用get-job来调查stdout

更新:我无法开始工作,轻松做我想要的,基本上是bash&operator.到目前为止,这是我最好的黑客

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
Run Code Online (Sandbox Code Playgroud)


小智 13

您可以使用PowerShell作业cmdlet来实现目标.

PowerShell中有6个与作业相关的cmdlet.

  • 获取在职
    • 获取当前会话中运行的Windows PowerShell后台作业
  • 接收 - 工作
    • 获取当前会话中Windows PowerShell后台作业的结果
  • 删除-工作
    • 删除Windows PowerShell后台作业
  • 启动工作
    • 启动Windows PowerShell后台作业
  • 停止 - 工作
    • 停止Windows PowerShell后台作业
  • 等待-工作
    • 禁止命令提示符,直到会话中运行的一个或所有Windows PowerShell后台作业完成

如果有意思,可以下载如何在PowerShell中创建后台作业的示例

  • 很好的答案,因为它涉及 Powershell 3+。作业 cmdlet 和之前的答案有什么区别? (2认同)

Mar*_*ski 10

从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>
Run Code Online (Sandbox Code Playgroud)

如果你想在后台执行几个语句,可以将&调用运算符,{ }脚本块和这个新的&后台运算符组合在一起,如下所示:

& { cd .\SomeDir\; .\SomeLongRunningOperation.bat; cd ..; } &
Run Code Online (Sandbox Code Playgroud)

以下是文档页面的更多信息:

来自PowerShell Core 6.0中的新功能:

支持带&符号的管道背景(&#)(#3360)

放在&管道的末尾会导致管道作为PowerShell作业运行.管道后台运行时,将返回作业对象.管道作为作业运行后,所有标准*-Jobcmdlet都可用于管理作业.管道中使用的变量(忽略特定于流程的变量)会自动复制到作业中,因此Copy-Item $foo $bar &只能起作用.作业也在当前目录而不是用户的主目录中运行.有关PowerShell作业的详细信息,请参阅about_Jobs.

来自about_operators/Ampersand背景运算符&:

&符背景操作员&

在PowerShell作业中运行管道之前的管道.&符背景操作符的作用类似于UNIX"&符号运算符",它在它作为后台进程之前运行命令.&符背景运算符构建在PowerShell作业之上,因此它具有很多功能Start-Job.以下命令包含&符背景运算符的基本用法.

Get-Process -Name pwsh &
Run Code Online (Sandbox Code Playgroud)

这在功能上等同于以下用法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
Run Code Online (Sandbox Code Playgroud)

产量

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
Run Code Online (Sandbox Code Playgroud)

有关PowerShell作业的更多信息,请参阅about_Jobs.

  • 感谢 100 个 MS 页面无法完成的精彩总结。 (3认同)

js2*_*010 6

你可以做这样的事情。

$a = start-process -NoNewWindow powershell {timeout 10; 'done'} -PassThru
Run Code Online (Sandbox Code Playgroud)

如果你想等待它:

$a | wait-process
Run Code Online (Sandbox Code Playgroud)

额外的 osx 或 linux 版本:

$a = start-process pwsh '-c',{start-sleep 5; 'done'} -PassThru 
Run Code Online (Sandbox Code Playgroud)

我有示例 pinger 脚本。args 作为数组传递:

$1 = start -n powershell pinger,comp001 -pa
Run Code Online (Sandbox Code Playgroud)


小智 5

太长了;博士

Start-Process powershell { sleep 30 }
Run Code Online (Sandbox Code Playgroud)


小智 0

我已经在 PowerShell v1.0 中成功使用了此处描述的解决方案http://jtruher.spaces.live.com/blog/cns!7143DA6E51A2628D!130.entry。在 PowerShell v2.0 中肯定会更容易。