如何在powershell脚本/函数中执行任意字符串,就像字符串实际上已经输入到脚本/函数中一样?

时间:2012-08-28 16:07:38

标签: variables powershell pipeline

我无法使用iex(invoke-expression)和变量来使用我的函数。我想要的是什么:

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提供了一个有用的提示。

2 个答案:

答案 0 :(得分:2)

我认为你在走路之前试图跑步。那就是说,让我们来看看你上面的第一个例子:

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

"hello" | my-function

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

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

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

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

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

答案 1 :(得分:0)

$inputa very weird special case automatic variable。完全依赖它是一个坏主意,更不用说与Invoke-Expression结合使用了。我猜$input只在函数体本身的范围内,并且在你动态调用的表达式的范围内消失。

我完全回应@ x0n的情绪。这听起来像一些真正的hacky,脆弱,难以调试,难以维护的东西。考虑一下你的目标,找出一些封装问题空间的标准函数和变量。阅读功能参数,管道参数等,这样您就可以利用最合适的解决方案,该解决方案得到了语言的适当支持。

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

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

'piped1', 'piped2' |  my-function