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は、バックグラウンドでプロセスを実行するという単純なユースケースでは過剰です。
注:最初の例では、sleepはPowershellコマンドレットであるため、「bg sleep 30」は機能しません。Start-Processは、実際にプロセスをフォークした場合にのみ機能します。
Start-Process
と、シェルの終了後も存続しますが、コンソールウィンドウから開始した場合は、そのウィンドウにバインドされたままになり、ウィンドウを閉じるとプロセスが終了します。
Start-Process
ため、これは機能しませんStart-Process {ping -n 1000 example.com > ping__example.com.txt }
。同じことがStart-Job
うまく機能します(ただし、出力ファイルへのフルパスを使用する必要があります)。
渡されたスクリプトブロックがコマンド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}
stdoutをリアルタイムで取得する方法はまだわかりません。start-jobでは、get-jobでstdoutをポーリングする必要があります
更新:基本的に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 { Write-Output 'Hello world' } | Receive-Job -Wait
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>
いくつかのステートメントをバックグラウンドで実行する場合は、次の&
ように、callオペレーター、{ }
スクリプトブロック、およびこの新しい&
バックグラウンドオペレーターを組み合わせることができます。
& { cd .\SomeDir\; .\SomeLongRunningOperation.bat; cd ..; } &
ドキュメントページからの詳細は次のとおりです。
アンパサンド(&)を使用したパイプラインのバックグラウンドのサポート(#3360)
&
パイプラインの最後に置くと、パイプラインがPowerShellジョブとして実行されます。パイプラインがバックグラウンド化されると、ジョブオブジェクトが返されます。パイプラインがジョブとして実行されると、すべての標準*-Job
コマンドレットを使用してジョブを管理できます。パイプラインで使用される変数(プロセス固有の変数は無視)は自動的にジョブにコピーされるため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}
機能的にはを使用するのと同じであるため
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」を参照してください。
Receive-Job 3
が、何も起こりません。
fg
と同様にそれを取得したいと考えていました。
fg
、私はそれを探して覚え:( PowerShellでは、しかし、何かを見つけることができませんでした
PowerShellジョブコマンドレットを使用して、目標を達成できます。
PowerShellでは、6つのジョブ関連のコマンドレットを使用できます。
それについて興味があれば、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スクリプトの例。引数は配列として渡されます:
$1 = start -n powershell pinger,comp001 -pa
start
プロセスをフォークし、呼び出し元に制御を返します。詳細はこちら
ここで説明されている解決策をhttp://jtruher.spaces.live.com/blog/cns!7143DA6E51A2628D!130.entryをPowerShell v1.0で正常に使用しました。PowerShell v2.0では間違いなく簡単になります。
Start-Job
、PSシェルが終了すると、何かで始まるものが殺されるようです。対照的Start-Process
に、PSシェルが終了した後、で開始されたものは引き続き実行されるようです。これは大きな違いです。