简体   繁体   English

在PowerShell中使用命令行参数运行可执行文件

[英]Running executable with command line parameters in PowerShell

This has to be possible. 这必须是可能的。 I am able to open a command prompt in windows and do the following: 我能够在Windows中打开命令提示符并执行以下操作:

<some exe> <some exe command line parameters>

There must be an equivalent way to do this in PowerShell or even a standard windows batch file. 在PowerShell甚至是标准Windows批处理文件中,都必须有等效的方法来执行此操作。 For example, from the windows command prompt I can start a docker container with: 例如,从Windows命令提示符下,我可以使用以下命令启动Docker容器:

docker run –-net=kafka -d –-name=zookeeper -e ZOOKEEPER_CLIENT_PORT=2181 confluentinc/cp-zookeeper:4.1.0

however if I try something like this with PowerShell 但是,如果我尝试使用PowerShell这样的操作

& "docker" run –-net=kafka -d –-name=zookeeper -e ZOOKEEPER_CLIENT_PORT=2181 confluentinc/cp-zookeeper:4.1.0

it fails with an generic error: 它失败并出现一般错误:

invalid reference format.

Perhaps PowerShell is not suited for this type of advanced use case. PowerShell可能不适合此类高级用例。 Any suggestions would be appreciated! 任何建议,将不胜感激!

Is there a better scripting language for advanced usages like this? 对于这样的高级用法,是否有更好的脚本语言?

By and large, external programs in PowerShell are called the same way as from cmd.exe - there are differences, due to PowerShell having additional metacharacters such as $ and @ , but they do not come into play in your specific case. 总体而言,PowerShell中的外部程序的调用方式与cmd.exe中的调用方式相同-有所不同,这是由于PowerShell具有其他元字符(例如$@ ,但在您的特定情况下它们不起作用。 (Your & "docker" ... variant would work in principle too, but the use of & is only necessary if you must use a quoted or variable-based command name or path). (您的& "docker" ...变体原则上也可以使用,但是仅在必须使用带引号基于变量的命令名称或路径时才需要使用& )。

The problem is that your original command line contains two instances of ( EN DASH, U+2013 ) instead of the expected ASCII-range - dash (hyphen) , which docker doesn't recognize. 问题是您的原始命令行包含两个实例EN DASH, U+2013 ),而不是 docker无法识别的预期ASCII范围-破折号(连字符)

A quick way to discover the problem: 快速发现问题的方法:

# Print the code points of characters outside the ASCII range.
PS> [int[]] [char[]] '& "docker" run –-net=kafka -d –-name=zookeeper -e ZOOKEEPER_CLIENT_PORT=2181 confluentinc/cp-zookeeper:4.1.0' -gt 127
8211
8211

Decimal 8211 is hex. 十进制8211为十六进制。 0x2013 , the code point of en-dash, whereas the code point of the regular - is 45 ( 0x2d ). 0x2013 ,连接划线的码点,而常规的代码点-450x2d )。

All that is needed is to replace these instances with - (and, since docker needn't be quoted, there is no need for & ): 所有需要的是取代这些与实例-和,因为docker不需要被引用,就没有必要对& ):

docker run --net=kafka -d --name=zookeeper -e ZOOKEEPER_CLIENT_PORT=2181 confluentinc/cp-zookeeper:4.1.0

Your own answer shows a variable-based implementation of the command that is effectively the same as the command above - if all the arguments are known in advance, there is never a need to use variables. 您自己的答案显示了命令的基于变量的实现,该实现与上面的命令实际上相同 -如果预先知道所有参数,则永远不需要使用变量。

If you do want to use variables, it is much simpler to use a single array variable for all the arguments and pass that: 如果确实要使用变量,则对所有参数使用单个数组变量并传递该变量要简单得多:

$dockerExe =  'docker'
$dockerArgs = 'run',
              '--net=kafka',
              '-d',
              '--name=zookeeper',
              '-e',
              'ZOOKEEPER_CLIENT_PORT=2181',
              'confluentinc/cp-zookeeper:4.1.0'

& $dockerExe $dockerArgs

Note: 注意:

  • The executable name/path must always be specified separately, and if it is quoted or involves variable references (as in this case), & , the call operator must be used for invocation, for syntactic reasons. 可执行文件的名称/路径必须始终单独指定,并且如果用引号引起来或涉及变量引用 (如本例中的& ,则出于语法原因,必须将调用运算符用于调用。

  • Passing the arguments as an array this way works with external programs; 这种方式将参数作为数组传递给外部程序。 for PowerShell commands, you'd create a hashtable variable that you pass with sigil @ instead of $ , a feature known as splatting . 对于PowerShell命令,您将创建一个哈希表变量,并使用sigil @而不是$传递,该功能称为splatting

I think Start-Process cmdlet will be useful. 我认为Start-Process cmdlet将很有用。 ArgumentList can be single or double quoted. ArgumentList可以单引号或双引号。

Start-Process docker -ArgumentList "run –-net=kafka -d –-name=zookeeper -e ZOOKEEPER_CLIENT_PORT=2181 confluentinc/cp-zookeeper:4.1.0"

There is a lot of complexities in powershell escaping. Powershell转义有很多复杂性。 I wrote this module to assist with running of external commands: 我写了这个模块来帮助运行外部命令:

https://github.com/choovick/ps-invoke-externalcommand https://github.com/choovick/ps-invoke-externalcommand

Demo: https://terminalizer.com/view/49acb54a979 演示: https : //terminalizer.com/view/49acb54a979

Install-Module -Name ExternalCommand -Scope CurrentUser
Invoke-ExternalCommand -Command "docker" -Arguments @("run","-d","--name=zookeeper","--net=kafka","-e","ZOOKEEPER_CLIENT_PORT=2181", "confluentinc/cp-zookeeper:4.1.0")

Here's how to do it. 这是操作方法。

$app = 'docker'

$a1 = 'run'

$a2 = '--net=kafka'

$a3 = '-d'

$a4 = '--name=zookeeper'

$a5 = '-e'

$a6 = 'ZOOKEEPER_CLIENT_PORT=2181'

$a7 = 'confluentinc/cp-zookeeper:4.1.0'

& $app $a1 $a2 $a3 $a4 $a5 $a6 $a7

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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