使用 start-process 時,與 unix "< /dev/null" 等效的 powershell 是什么?在 unix 中,我會這樣做:“myprogram.exe arg1 arg2 < /dev/null”:
我使用 start-process 在 powershell 中嘗試了相同的方法:
Start-Process -RedirectStandardInput $null -FilePath powershell.exe -ArgumentList "myprogram.exe arg1 arg2"
錯誤訊息,它不起作用:
Start-Process : Cannot validate argument on parameter 'RedirectStandardInput'. The argument is null or empty. Provide an argument that is not null or
empty, and then try the command again.
At line:1 char:38
Start-Process -RedirectStandardInput $null -FilePath powershell.exe - ...
~~~~~
CategoryInfo : InvalidData: (:) [Start-Process], ParentContainsErrorRecordException
FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.StartProcessCommand
uj5u.com熱心網友回復:
必須有更好的方法:
PS> $temp = New-TemporaryFile
PS> start-process powershell.exe -ArgumentList "gci C:\" -nnw -wait -RedirectStandardInput $temp
這有效,但它會在臨時檔案夾中創建一百萬個空檔案以進行清除。
另一種可能:
PS> start-process powershell.exe -ArgumentList "`$null `| gci C:\" -nnw -wait
uj5u.com熱心網友回復:
使用直接同步呼叫:
# Provide empty stdin input to myprogram.exe
# Equivalent to the following in a Unix shell:
# myprogram.exe arg1 arg2 </dev/null
@() | myprogram.exe arg1 arg2
筆記:
$null,正如js2010 所建議的那樣,也可以作業,但僅適用于外部程式- PowerShell命令將接收實際$null作為輸入。- 相比之下,
@()(一個空陣列)始終不通過管道發送任何內容(外部程式通過 stdin 接收管道輸入),因為它是正在發送的陣列元素,一個一個 - 如果有的話 - 和一個空陣列的定義沒有元素)。
使用異步默認 Start-Process呼叫:
筆記:
Start-Process僅在不尋常的呼叫場景中需要,例如需要在新的控制臺視窗中啟動命令(包括提升)或需要以不同的用戶身份運行);要同步執行 CLI 及其連接到 PowerShell 的流,請使用上面顯示的直接呼叫技術。有關何時Start-Process合適或不合適的指導,請參閱GitHub 檔案問題 #6239。
從 PowerShell 7.2 開始,您只能將檔案路徑傳遞給Start-Process'-Redirect*引數。
- GitHub 問題 #5184提出了一個潛在的未來增強功能,它也允許使用變數,使用諸如
variable:null
因此,要有效地通過空標準輸入輸入Start-Process,您必須確實使用-RedirectStandardInput(臨時)空檔案(0位元組),如您自己的答案所示。
在類 Unix平臺上,您應該能夠使用
-RedirectStandardInput /dev/null,但由于長期存在的錯誤,它在 PowerShell 7.2.1 中不起作用:不是沒有標準輸入,而是發送換行符- 請參閱GitHub 問題 #8702。也就是說,Start-Process在 Unix 上很少有用,因為它無法在新視窗中啟動行程。在 Windows 上,不幸的是,洗掉臨時檔案需要等待啟動的程式退出,因為在此之前檔案被鎖定。因此,為了可靠地清理以這種方式使用的臨時檔案,您必須使用:
-Wait, 使呼叫同步-PassThru,System.Diagnostics.Process回傳一個您可以稍后監視行程是否已退出(通過.HasExited或.WaitForExit())的回傳值。
但是,有一個解決方法:通過呼叫cmd.exe并使用其 <NUL重定向(相當于</dev/nullUnix):
# Parameters -FilePath and -ArgumentList positionally implied.
Start-Process cmd.exe '/c "myprogram.exe arg1 arg2 <NUL"'
或者,如果您無論如何都需要一個新的 PowerShell 實體,您可以在傳遞的命令列中使用其直接呼叫語法:
Start-Process powershell.exe '-c "@() | myprogram.exe arg1 arg2"'
筆記:
該
cmd系的解決方法是更快和更輕質的,并且因此如果呼叫的更好的選擇myprogram.exe是唯一所需的操作。更一般地說,委托 to
cmd.exe的管道和重定向運算子(以及類似地,/bin/sh在 Unix 上的 to )是一種解決方法,可以解決 PowerShell 的管道目前無法作為原始位元組管道的限制,如果嘗試會導致資料損壞例如,使用 捕獲原始位元組輸出>;Start-Process'-Redirect*引數同上- 請參閱此答案。通過此答案中詳述的額外作業,您還可以通過
System.Diagnostics.Process如下所示的相關 .NET API實作原始位元組處理。
與直接使用的System.Diagnostics.Process-相關.NET的API:
注意:
- 您將無法以這種方式在新的控制臺視窗中啟動該行程,因為這需要將
System.Diagnostics.ProcessStartInfo實體的.UseShellExecute屬性設定為$true,而使用了.RedirectStandardInput排除。
# Configure the process to launch.
$ps = [System.Diagnostics.Process] @{
StartInfo = [System.Diagnostics.ProcessStartInfo] @{
FileName = 'myprogram.exe'
Arguments = 'arg1 arg2'
UseShellExecute = $false # Required for use of .Redirect* properties
RedirectStandardInput = $true # Provide stdin input programmatically below
WorkingDirectory = $PWD.ProviderPath # Use PowerShell's current dir.
}
}
$null = $ps.Start() # Launch asynchronously
$ps.StandardInput.Close() # Close stdin, effectively providing no input.
$ps.WaitForExit() # Wait for the process to exit.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/399972.html
標籤:电源外壳
上一篇:Azure函式臨時檔案
