powershell 点源命令字符串与其他参数

hlswsv35  于 2023-06-23  发布在  Shell
关注(0)|答案(3)|浏览(144)

我需要从PowerShell执行一个字符串形式的外部命令。
是否可以通过dot-sourcing或类似的方式运行带有参数的外部命令(本例中为ping)?
或者你必须使用Invoke-Expression?

# This works:
$commandText = "ping"
. "$commandText"

# This results in: The term 'ping -t 127.0.0.1' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
$commandText = "ping -t 127.0.0.1"
. "$commandText"

我试过&并引用了参数,但没有任何效果。

zpjtge22

zpjtge221#

如果你 * 给定 * 一个字符串代表 * 整个命令行*-即一个包含可执行文件名/路径 * 及其参数 * 的字符串,你确实不能 * 使用.,点源操作符,也不能使用&,调用操作符,因为这些操作符只接受可执行文件的 * 名称或路径 * 作为它们的第一个参数,而可执行文件的 * 参数 * 需要 * 单独 * 指定。

  • 相比之下,如果您想 * 自己 以编程方式 * 构造命令行,请使用Luuk's answer中所示的基于数组的技术。
  • 请注意,对于 * 外部程序 *(如ping),.的行为与&相同-仅对于 *PowerShell脚本 * 或 * 脚本块 ,这些运算符的行为不同:.直接在调用者的作用域 * 中运行脚本(块)&-更常见的情况是-在 * 子 * 作用域中运行它。

还要注意的是,使用&来调用脚本和外部程序,其名称/路径既不带引号,也不通过变量表示,这是 * 可选的 *。

Invoke-Expressioniex-其中should generally be avoided-是最简单的解决方案,但通常的警告适用:

  • 鉴于Invoke-Expression允许执行存储在字符串中的任意代码,请确保您“完全控制”或“隐式信任”字符串的内容。
$commandText = "ping -t 127.0.0.1"
# !! Be sure that you trust $command to do what you expect.
Invoke-Expression $commandText

或者,您可以创建一个script block{ ... },然后使用&按需调用-但请注意,这涉及与使用Invoke-Expression相同的风险

$commandText = "ping -t 127.0.0.1"

# Parse the command line into a script block.
$scriptBlock = [scriptblock]::Create($commandText)

# Invoke the script block, which you can do repeatedly.
& $scriptBlock
  • 对于重复调用,这比每次都使用Invoke-Expression稍微更有效,尽管这在实践中可能并不重要。
  • 至少假设,您可以使用该技术支持在每次调用时传递额外的参数 ad hoc@args是自动$args变量的splatted form);例如:
$commandText = 'cmd /c echo one'

# Append @args to the original command line, which expands to
# to the arguments passed on invocation of the script block.
# Note: 
#   Placing @args *last* may not always work.
$scriptBlock = [scriptblock]::Create($commandText + ' @args')

# Pass additional arguments on invocation.
# -> 'one two three'
& $scriptBlock two three

如果命令行是为 * 其他shell / 非shell * 调用编写的:**

cmd.exe和无shell调用上下文(如计划任务)编写的命令行 * 在由PowerShell直接执行时可能有效,也可能无效,这取决于特定的命令,这是由于PowerShell的参数语法不同。
值得注意的是,PowerShell有 * 更多 * metacharacters需要引用或转义,如@(){},其转义字符(```,所谓的反勾号)是不同的(cmd.exe使用^)。
在这种情况下,最简单的方法是将命令行传递给cmd.exe CLI,使用其**/c**参数:

$commandText = "ping -t 127.0.0.1"
# Let cmd.exe execute the command line, via cmd /c
cmd /c $commandText

注意事项:

  • 在类Unix平台上,使用/bin/sh -c $commandText
lnlaulya

lnlaulya2#

将参数放入数组中:

$commandText = "ping"
[string[]]$a = "-t","127.0.0.1"
 . "$commandText" $a

输出:

PS D:\TEMP> . "$commandText" $a

Pinging 127.0.0.1 with 32 bytes of data:
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128
Reply from 127.0.0.1: bytes=32 time<1ms TTL=128

Ping statistics for 127.0.0.1:
    Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms
Control-C
py49o6xq

py49o6xq3#

将命令放入脚本块中,并将其转换为脚本块。这可以通过调用操作符&来调用。具体如下:

$command = [scriptblock]{ping -t 127.0.0.1 }
'Getting ready to run the command inside the variable'
& $command

相关问题