Powershell调用或执行(使用&运算符)带参数的函数?

huangapple go评论56阅读模式
英文:

Powershell invoke or execute (with & operator) a function with arguments?

问题

这段 PowerShell 代码的问题在于,您希望将$temp$cFunc放在同一行并且正常工作。但是,您提供的第二个示例中的代码是不正确的,无法在同一行实现这个目标。

英文:

I've got this ps snippet:

function myFuncWithArgs($arg) { 
    Write-Output $arg 
}

$temp = 'sometext'

$cFunc = 'myFuncWithArgs' 
& $cFunc $temp

it works but I need the $temp to be on the same line as $cFunc and work the same. This does not work:

$cFunc = 'myFuncWithArgs' $temp
& $cFunc

is this possible in pshell?

答案1

得分: 4

看起来您正在尝试将一个完整的命令(可执行文件+参数)存储在变量中,以便以后按需执行。

请使用脚本块(`{ ... }`)来完成此操作,然后您可以使用`&`[调用运算符](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Operators#call-operator-))随时调用它:

将完整的命令定义为脚本块。

$scriptBlock = { myFuncWithArgs $temp }

调用它。

您也可以传递参数给它,但只有在它被设计为接受它们时才有意义,例如通过$args

& $scriptBlock


注意:
 * `&` 不适用于包含完整命令的字符串。它的参数必须是一个脚本块,如上所示,或命令名称或可执行文件路径,并且传递给该脚本块/命令/可执行文件的任何参数都必须单独指定,例如  
`& { Write-Output $args } arg1 ...` 或 `& $pathToExecutable arg1 ...`  
 * 请继续阅读如何执行存储在字符串中的完整命令,这可能是一个安全风险,但是。

---

上述示例使用了一个脚本块文字。  
要从字符串中创建脚本块,请使用[`[scriptblock]::Create()`](https://learn.microsoft.com/zh-cn/dotnet/api/System.Management.Automation.ScriptBlock.Create):

重要提示:

请确保您要么完全控制这个字符串的内容,要么隐式信任它,以防止执行不必要的代码。

$commandString = 'myFuncWithArgs $temp'

$scriptBlock = [scriptblock]::Create($commandString)

& $scriptBlock


您提到了[`Read-Host`](https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.utility/read-host),即提示用户的命令字符串来源,这种情况下上面的“重要提示”绝对适用。

* _如果_ 您接受执行任意用户提供的命令的风险,您可以简单地使用[`Invoke-Expression`](https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.utility/invoke-expression) `$commandString` - 但请注意,通常不鼓励使用`Invoke-Expression`,因为它能够执行存储在字符串中的任意代码。

* 但是,存在一种中间方式,_确实_ 需要使用 `[scriptblock]::Create()`:
  * 在调用脚本块之前,您可以调用其[`.CheckRestrictedLanguage()`](https://docs.microsoft.com/zh-cn/dotnet/api/System.Management.Automation.ScriptBlock.CheckRestrictedLanguage)方法,以确保生成的命令仅包含在`Restricted`[语言模式](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Language_Modes)中允许的命令,以及允许的特定命令和变量的可配置性。
英文:

<!-- language-all: sh -->

It looks like you're trying to store a complete command (executable + arguments) in a variable for later execution on demand.

Use a script block ({ ... }) for that, which you can call on demand with &amp;, the call operator:

# Define the full command as a script block.
$scriptBlock = { myFuncWithArgs $temp }

# Invoke it.
# You may also pass arguments to it, but that only makes sense
# if it is designed to accept them, e.g. via $args
&amp; $scriptBlock

Note:

  • &amp; does not work with a string containing a complete command. Its argument must either be a script block, as shown, or command name or executable path, and any arguments to pass to that script block / command / executable must be specified separately, e.g.
    &amp; { Write-Output $args } arg1 ... or &amp; $pathToExecutable arg1 ...
  • Read on for how execute a complete command stored in a string, which can be a security risk, however.

The above uses a script-block literal.
To create a script block from a string, use [scriptblock]::Create():

# IMPORTANT: 
#  Be sure that you either fully control or implicitly trust
#  the content of this string, so as to prevent execution of unwanted code.
$commandString = &#39;myFuncWithArgs $temp&#39;

$scriptBlock = [scriptblock]::Create($commandString)

&amp; $scriptBlock

You mention Read-Host, i.e. prompting the user, as the source of your command string, in which case the caveat under "IMPORTANT:" above definitely applies.

  • If the risk of execution arbitrary user-supplied commands is acceptable to you, you could simply use Invoke-Expression $commandString - but note that Invoke-Expression is generally discouraged precisely for its ability to execute arbitrary code stored in a string.

  • However, there is middle ground, which does require [scriptblock]::Create():

    • Before invoking the script block, you can call its .CheckRestrictedLanguage() method to ensure that the resulting command only contains commands permitted in Restricted language mode, with configurability as to which specific commands and variables are permitted.

答案2

得分: 2

你可以同时为多个变量赋值,从而保持在同一行:

$cFunc,$cArgs = 'myFuncWithArgs',$temp
& $cFunc @cArgs
英文:

You can assign to multiple variables at once, thus keeping things on the same line:

$cFunc,$cArgs = &#39;myFuncWithArgs&#39;,$temp
&amp; $cFunc @cArgs

答案3

得分: 0

调用函数时不使用括号,参数之间不用逗号,用空格隔开。

function Dartagnan($a, $b)
{
    $c = $a + $b;
    Write-Host $c;
    #result is 12;
}
Dartagnan 5 7;
Read-Host;
英文:

Invoke the function without brackets, and the parameters without commas and with white spaces.

function Dartagnan($a, $b)
{
$c = $a + $b;
Write-Host $c;
#result is 12;
}
Dartagnan 5 7;
Read-Host;

huangapple
  • 本文由 发表于 2023年4月19日 21:23:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76055061.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定