英文:
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 &
, 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
& $scriptBlock
Note:
&
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.
& { Write-Output $args } arg1 ...
or& $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 = 'myFuncWithArgs $temp'
$scriptBlock = [scriptblock]::Create($commandString)
& $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 thatInvoke-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 inRestricted
language mode, with configurability as to which specific commands and variables are permitted.
- Before invoking the script block, you can call its
答案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 = 'myFuncWithArgs',$temp
& $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;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论