0

我无法使用带有变量的 iex(调用表达式)使我的函数工作。我想要的是:

function My-Function {

    # code that constructs $command 
    #$command is an arbitrary string that may contain pipes, 
    #variables, command line paramaters, switchs, quoted strings, THE LOT!

    Execute-My-Command-Exactly-As-Though-I-Had-Typed-It-Here $command
}

例如

function My-Function {
    $command = "`$input | select-string hello"

    iex $command
}

这样做(之后。包括我包含上述功能的文件)

PS C:\> echo "hello" | My-Function
PS C:\>

但显然它应该这样做:

PS C:\> echo "hello" | My-Function

hello


PS C:\>

此外,在实际命令行中,变量 DO 似乎被 iex 拾取:

PS C:\> $hello = "hello"
PS C:\>
PS C:\> iex "`$hello | select-string hello"

hello


PS C:\>

我能想到的唯一解决方法是将函数实际写入文件,然后 . 包括它,然后调用它。但这太可怕了!一个好的 shell 脚本语言的全部意义在于它应该能够轻松地完成这些元数据。

解决方案:

PowerShell 无法做到这一点,尽管 latkin 提供了一个有用的提示。

4

2 回答 2

2

我想你是想在你能走路之前先跑。也就是说,让我们看一下上面的第一个示例:

function my-function {
    process {
       $_ | select-string "hello"
    }    
}

"hello" | my-function

现在,你可能会对自己说:“嘿,这不是我问的!” 对此,我对 Invoke-Expression (iex) 提出以下建议:执行这样的任意文本可能很危险,而且很少需要。它通常表明对构建可互操作的功能和模块缺乏了解。即使是一次性脚本也很少需要 IEX。

所以,我不只是把它留在那里,但如果没有对你正在尝试做的事情的更高层次的观点,我无法合理地回答你的问题。听起来您正在尝试概括一些执行脚本或脚本的过程。因此,我的建议是研究在 PowerShell 中执行此操作的各种本机机制,即点源 (.) 和调用 (&) 运算符。

最后,喝杯咖啡,坐下来阅读 Keith Hill 最优秀的“Effective Windows PowerShell”免费电子书:

http://rkeithhill.wordpress.com/2009/03/08/effective-windows-powershell-the-free-ebook/

前几章将帮助您在学习正确的做事方式时帮助自己。它涵盖了 PowerShell 的主要工具:get-command、get-help、get-member 并了解命令表达式模式之间的区别。

于 2012-08-28T16:31:01.627 回答
0

$input一个很奇怪的特例自动变量。完全依赖它是一个坏主意,更不用说与Invoke-Expression. 我猜$input只是在函数体本身的范围内,并且在您动态调用的表达式的范围内消失。

我完全赞同@x0n 的观点。这听起来像是一些非常hacky,脆弱,难以调试,难以维护的东西。想想你的目标,找出一些封装问题空间的标准函数和变量。阅读函数参数、管道参数等,这样您就可以利用得到语言适当支持的最佳解决方案。

话虽这么说...您可以通过创建一个脚本块来解决此问题,该脚本块允许从外部传递参数。

function My-Function{
    & ([scriptblock]::Create('param($newInput); "Newinput is $newInput"')) $input
}

'piped1', 'piped2' |  my-function
于 2012-08-28T16:59:44.337 回答