如何在没有中间变量的情况下将cmdlet输出作为参数传递给应用程序(.exe)?

时间:2018-07-06 17:26:34

标签: powershell

我有以下PS命令返回一个字符串:

(get-date -Uformat %s).remove(10, 1).substring(5,9)

我想从当前目录中调用应用程序myapp.exe,并以该PS命令的结果作为参数,并且我想在一行中执行此操作(无中间变量)。它的语法是什么?

换句话说,我正在bash中寻找与$(<command>)等效的Powershell。

3 个答案:

答案 0 :(得分:1)

我认为您正在寻找这个:

command ((get-date -Uformat %s).remove(10, 1).substring(5,9))

但是即使没有()

,您的命令也应该可以工作

答案 1 :(得分:1)

您可以使用Invoke-Expression,但是请记住,使用此cmdlet时需要考虑安全方面的考虑,因为它可能使您容易受到代码注入攻击。另请注意,即使基础命令因错误而失败,Invoke-Expression通常也会成功。

$command = "myapp.exe '$((get-date -Uformat %s).remove(10, 1).substring(5,9))'"
Invoke-Expression $command

如果要检查命令是否成功,请检查$LASTEXITCODE以获取合适的退出代码,然后根据该代码继续/失败。请注意,$LASTEXITCODE仅在检查程序结果而非cmdlet时有效。

避免使用Invoke-Expression

您可以通过构建一个传递给命令行应用程序的参数数组来避免使用Invoke-Expression,就像这样(在您的情况下,它只是一个参数,但是可以扩展以构建更多参数)同样具有多个参数的复杂命令,只需为每个开关,参数或值添加其他数组元素):

$cmdargs = @(
  ( GetDdate -Uformat %s ).Remove( 10, 1 ).Substring( 5,9 )
)
myapp.exe $cmdargs

您仍然可以通过检查$LASTEXITCODE的值来跟踪命令的成功。

保持简单

在您的情况下,您只需调用myapp.exe (get-date -Uformat %s).remove(10, 1).substring(5,9),它将插入日期字符串作为参数。但是,当您要基于多种条件构建更复杂的命令时,上述技术(构建数组是Invoke-Expression的首选方法)很有用。

答案 2 :(得分:1)

./myapp.exe (get-date -Uformat %s).remove(10, 1).substring(5,9)
  • ./myapp.exe(或.\myapp.exe)调用位于当前目录中的可执行文件myapp.exe

    • 如果myapp.exe位于$env:PATH中列出的目录中,请使用./ \ .\前缀。
    • 无论哪种方式,生成的进程都会在当前目录(文件系统提供者位置)中运行
  • 以适当的方式在 argument模式下解析传递给可执行文件的参数(请参见Get-Help about_Parsing),并且如何解释给定的参数(以空格分隔)取决于其第一个字符

    • 由于第一个字符是(,因此该参数将被评估为表达式(以表达式模式解析);该表达式求值的结果将传递给可执行文件。
      位于第一位置的其他特殊字符为$@'"(请参阅下一点)。

      • 请注意,虽然$(...)-子表达式运算符(请参见Get-Help about_Operators)-在这种情况下也可以工作,但仅将计算一个单个表达式((...)-仅在您要传递多个语句的输出时才需要$(...)
    • '...'自变量的内容(单引号)被视为文字,而"..."自变量的内容则是可扩展字符串(松散地说,是一个内插$前缀标记的字符串)。

    • 基本上,其他任何参数(未加引号且不以(@$开头)都是隐式< / em>被视为可扩展字符串,即好像您已将其括在"..."中一样。

    • 有关如何在参数模式下解析未"..."'...'中未明确包含的参数的全面概述,请参见我的this answer

      • 有关在这种情况下可能令人惊讶的行为,请参见this GitHub issue