简体   繁体   中英

Start-Process -RedirectStandardInput $null -FilePath powershell.exe -ArgumentList "myprogram.exe arg1 arg2"

What's the powershell equivalent of unix "< /dev/null" when using start-process? In unix i would do: "myprogram.exe arg1 arg2 < /dev/null":

I tried the same in powershell using start-process:

 Start-Process -RedirectStandardInput $null -FilePath powershell.exe -ArgumentList "myprogram.exe arg1 arg2"

Error message, it doesn't work:

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

There's got to be a better way:

PS> $temp = New-TemporaryFile
PS> start-process powershell.exe -ArgumentList "gci C:\" -nnw -wait -RedirectStandardInput $temp 

this works but it will create a million empty files in the temp folder to purge.

Another possibility:

PS> start-process powershell.exe -ArgumentList "`$null `| gci C:\" -nnw -wait

With direct, synchronous invocation:

# Provide empty stdin input to myprogram.exe
@() | myprogram.exe arg1 arg2

Note: $null , as js2010 suggests, works too, but only with external programs - a PowerShell command would receive an actual $null as input.


With an asynchronous-by-default Start-Process call :

As of PowerShell 7.2, you can only pass file paths to the -Redirect* parameters.

  • GitHub issue #5184 suggest a potential future enhancement that would also allow use of variables , using notation such as variable:null

Therefore, to effectively pass empty stdin input via Start-Process , you must indeed use -RedirectStandardInput with a (temporary) empty file ( 0 bytes) , as shown in your own answer .

  • On Unix -like platforms, where you should be able to use -RedirectStandardInput /dev/null , that doesn't work as of PowerShell 7.2.1 due to a long-standing bug : instead of no stdin input, a newline is sent - see GitHub issue #8702 . That said, Start-Process is rarely useful on Unix, due to its inability there to launch a process in a new window .

  • On Windows, deleting the temporary file unfortunately requires waiting for the launched program to exit , because the file is locked until then. Therefore, in order to reliably clean up a temporary file used this way you'll have to either use:

    • -Wait , to make the call synchronous
    • -PassThru , to have a System.Diagnostics.Process returned that you can later monitor for whether the process has exited (via .HasExited or .WaitForExit() ).

However, there is a workaround : Call via cmd.exe and use its <NUL redirection (the equivalent of </dev/null in Unix):

# Parameters -FilePath and -ArgumentList positionally implied.
Start-Process cmd.exe '/c "myprogram.exe arg1 arg2 <NUL"'

Or, if you're need a new PowerShell instance anyway, you can use its direct-invocation syntax in the command line you pass:

Start-Process powershell.exe '-c "@() | myprogram.exe arg1 arg2"'

Note: The cmd -based workaround is faster and more light-weight, and therefore the better choice if the invocation of myprogram.exe is the only required operation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM