[英]What exactly does the call operator in PowerShell do?
我有一個Powershell腳本,該腳本使用調用運算符運行一些可執行文件。 像這樣:
$executable = 'c:\dev\test.exe'
& $executable | Out-Host
Write-Host 'done'
該test.exe
依次運行另一個程序( server.exe
)並通過TCP / IP與之通信(該程序需要管理特權,並且由於我的powershell腳本以admin身份運行),因此它還運行了瑣碎的批處理腳本(該腳本可以運行並在1秒后終止)。 一旦啟動, server.exe
將運行直到被test.exe
終止。 涉及的所有程序都是控制台應用程序。 可能另一個值得注意的事實是,由於server.exe
需要管理員權限,因此它在與test.exe
分開的控制台窗口中運行。
有時, test.exe
不會終止server.exe
(有時是由於崩潰,有時是由於其中的錯誤)。 發生這種情況時, test.exe
終止執行后不會返回Powershell腳本(我看不到正在打印“完成”)。 如果我手動終止server.exe
,我會立即在Powershell控制台中看到“完成”。 為什么會這樣呢? 為什么Powershell等待進程終止,而該進程尚未啟動並且甚至沒有在同一控制台中運行?
在我的調查嘗試中,我嘗試使用更少的代碼來重現此問題,我創建了僅運行server.exe
test2.exe
(完全相同,我可以訪問test.exe
源代碼)並終止。 現在,當我運行相同的powershell腳本,但使用test2.exe
作為$executable
,我完全可以看到最初的期望: server.exe
在單獨的窗口中啟動,然后在powershell窗口中打印“ done”(powershell腳本終止)雖然server.exe
仍然運行。
我在運行test.exe
同時觀看了Process Explorer,並且我確定test.exe
終止后除了server.exe
之外沒有其他進程在運行。
我沒有找到任何深入的解釋, &
操作符做什么以及它等待什么,也許您有一些想法?
更新:我沒有使用呼叫運算符運行,而是嘗試了Start-Process
:
$executable = 'c:\dev\test.exe'
Start-Process $executable -Wait
Write-Host 'done'
現在, test.exe
在其自己的控制台中運行,終止並且powershell仍在等待server.exe
完成。
我也嘗試運行批處理腳本:
c:\dev\test.exe
echo done
並且工作正常: test.exe
終止后,“ done”將立即打印到控制台,並且批處理文件停止( server.exe
仍在運行)。
另一個更新:更改腳本以執行以下操作:
$executable = 'c:\dev\test.exe'
$proc = Start-Process $executable -PassThru
do {
Get-Process -Id $proc.Id
Start-Sleep -Seconds 10
} while ($true)
我在運行test.exe
幾次Get-Process
常規Get-Process
輸出,然后(在test.exe
終止后)它開始產生“找不到進程標識符為3028的進程”錯誤。 所以我大概可以走這條路。
我嘗試過的另一件事是:
$env:PATH += ';c:\dev\;'
test.exe
Write-Host 'done'
盡管如此,還是沒有運氣: test.exe
終止,powershell仍然等待server.exe
終止。
也嘗試了工作方法:
$job = Start-Job {& 'c:\dev\test.exe'}
do
{
$job
Start-Sleep -Seconds 10
} while ($job.JobStateInfo.State -eq [System.Management.Automation.JobState]::Running)
Receive-Job $job
除非我終止server.exe
否則它永遠不會退出。
呼叫操作&
簡單試圖調用它后面的命名命令(應用程序,腳本,函數,cmdlet的),傳遞任何額外的參數的命令。 此外, &
在新范圍內執行命令,而.
在當前范圍內執行命令。 執行應用程序(exe)時,在新作用域中執行並不重要。 該exe文件不會影響PowerShell中的作用域變量。
由於存在test.exe行為,因此在控制台exe完成之前,PowerShell不會將控制權返回給腳本。 Test.exe和test2.exe都是控制台子系統exes對嗎? PowerShell與Windows子系統exe的行為有所不同。 它將啟動它們並立即返回,除非您使用諸如notepad.exe | Out-Null
這樣的技巧notepad.exe | Out-Null
notepad.exe | Out-Null
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.