Powershell: Pipe external command output to another external command

被刻印的时光 ゝ 提交于 2019-12-07 17:32:21

问题


How can I get PowerShell to understand this type of thing:

Robocopy.exe | Find.exe "Started"

The old command processor gave a result, but I'm confused about how to do this in PowerShell:

&robocopy | find.exe "Started"                #error
&robocopy | find.exe @("Started")             #error
&robocopy @("|", "find.exe","Started")        #error
&robocopy | &find @("Started")                #error
&(robocopy | find "Started")                  #error

Essentially I want to pipe the output of one external command into another external command. In reality I'll be calling flac.exe and piping it into lame.exe to convert FLAC to MP3.

Cheers


回答1:


tl;dr

robocopy.exe | find.exe '"Started"'    # Note the nested quoting.

For an explanation of the nested quoting, read on.


PowerShell does support piping to and from external programs.

The problem here is one of parameter parsing and passing: find.exe has the curious requirement that its search term must be enclosed in literal double quotes.

In cmd.exe, simple double-quoting is sufficient: find.exe "Started"

By contrast, PowerShell by default pre-parses parameters before passing them on and strips enclosing quotes, so that find.exe sees only Started, without the double quotes, resulting in an error.

There are two ways to solve this:

  • PS v3+ (only an option if your parameters are only literals and/or environment variables): special parameter --% tells PowerShell to pass the rest of the command line as-is to the target program (reference environment variables, if any, cmd-style (%<var>%)):
    robocopy.exe | find.exe --% "Started"

  • PS v2-, or if you need to use PowerShell variables in the parameters: apply an outer layer of PowerShell quoting (PowerShell will strip the single quotes and pass the contents of the string as-is to find.exe, with enclosing double quotes intact):
    robocopy.exe | find.exe '"Started"'




回答2:


Invoke it via cmd:

PS> cmd /c 'Robocopy.exe | Find.exe "Started"'



回答3:


@Jobbo: cmd and PowerShell are two different shells. Mixing them is sometimes possible but as you realized from Shay's answer, it won't get you too far. However, you may be asking the wrong question here.

Most of the time, the problem you are trying to solve like piping to find.exe are not even necessary. You do have equivalent of find.exe, in fact more powerful version, in Powershell: select-string

You can always run a command and assign results to a variable.

$results = Robocopy c:\temp\a1 c:\temp\a2 /MIR

Results are going to be STRING type, and you have many tools to slice and dice it.

PS > $results |select-string "started"

  Started : Monday, October 07, 2013 8:15:50 PM


来源:https://stackoverflow.com/questions/19220933/powershell-pipe-external-command-output-to-another-external-command

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!