Variables 如何在powershell脚本/函数中执行任意字符串,就好像该字符串实际上已输入到脚本/函数中一样?
我无法使用带有变量的iex(调用表达式)使函数工作。我想要的是:Variables 如何在powershell脚本/函数中执行任意字符串,就好像该字符串实际上已输入到脚本/函数中一样?,variables,powershell,pipeline,Variables,Powershell,Pipeline,我无法使用带有变量的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-Com
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
hello
PS C:\>
此外,在实际的命令行上,iex似乎可以提取变量:
PS C:\> $hello = "hello"
PS C:\>
PS C:\> iex "`$hello | select-string hello"
hello
PS C:\>
我能想到的唯一解决办法是将函数写入文件,然后。包括它,然后调用它。但这太可怕了!一个好的shell脚本语言的全部要点是它应该能够轻松地完成这些元任务
解决方案:
PowerShell无法做到这一点,尽管latkin提供了一个有用的提示。我想你是想先跑后走。也就是说,让我们看看上面的第一个例子:
function my-function {
process {
$_ | select-string "hello"
}
}
"hello" | my-function
现在,您可能会对自己说:“嘿,我不是这么问的!”对此,我提供以下关于调用表达式(iex)的建议:执行这样的任意文本可能很危险,而且很少需要。它通常表示缺乏对构建可互操作功能和模块的理解。即使是一次性脚本也很少需要IEX
所以,我不打算就此置之不理,但如果没有更高层次的观点,我无法合理地回答你的问题。听起来好像您正试图概括执行脚本的某个或多个过程。因此,我的建议是研究在PowerShell中执行此操作的各种本机机制,即点源(.)和调用(&)操作符
最后,喝杯咖啡,坐下来阅读Keith Hill最优秀的“高效Windows PowerShell”免费电子书:
前几章将帮助你学会正确的做事方式。它涵盖了PowerShell的主要工具:get命令、get帮助、get成员以及了解命令和表达式模式之间的区别 $input
是。完全依赖它是个坏主意,更不用说与Invoke Expression
结合使用了。我猜,$input
仅在函数体本身的范围内,并且在动态调用的表达式的范围内消失
我完全赞同@x0n的观点。这听起来像是一些非常粗糙、脆弱、难以调试、难以维护的东西。仔细考虑你的目标,找出一些标准的函数和变量来封装问题空间。阅读函数参数、管道参数等,这样您就可以利用最佳适当的解决方案,该解决方案具有语言的适当支持
话虽如此。。。您可以通过创建一个scriptblock来解决这个问题,它允许从外部传递参数
function My-Function{
& ([scriptblock]::Create('param($newInput); "Newinput is $newInput"')) $input
}
'piped1', 'piped2' | my-function
你到底想完成什么?为什么?对您试图解决的高级别问题有了更多的了解,我们可能会找到一个更为强大的答案。:)在bash中,如果$command包含脚本/命令行的一行,我们可以使用“$command”行调用它,当然,在WeakShell中,它只将$command作为文本输出。我想要的是执行-My-Command-Execute-As-I-Had-Typed-It-Here:P@samthebest:使用调用运算符调用powershell中的另一个命令:&$command--使用脚本块(lambda/匿名函数)调用一组命令:&{cmd1;cmd2}True,即。然而,我预见到了他的下一个痛点,即没有意识到需要单引号来防止参数$newInput的变量扩展。对于一个绝对的新手来说,即使是简单的例子也不那么简单。谢谢,这真的很有帮助,几乎是我想要的,我想这是WeakShell允许的。声明和传递变量将是一件痛苦的事情,但我可以很容易地让一个预处理器来做这件事。是的,似乎VerboseShell的范围规则是它的陷阱之一。嗯。。。“weakshell?”“verboseshell?”我看到你在努力为自己的无能或不愿意学习新东西辩护。干得好而不是抱怨Windows是如何运行的!=Unix或PS!=巴什,上课要专心。你会成为一个更好的人的。我只是高兴地说,这是软弱和冗长的,因为我相信这是真的!该线程提供了1000多个PS无法完成但bash可以完成的示例之一。与其试着读懂我的心思,挑起争论,不如在课堂上集中注意力。你会是一个更好的人。你认为powershell比bash更冗长吗?现在我已经听到了一切。感谢这本书,是的,像man和gm这样的命令非常有用(显然没有bash等价物P的一半有用)。您不喜欢执行任意文本通常表明您不了解元脚本的功能。语言的表达能力越强,我们就越能抽象出结构,这会导致完全枯燥的代码,这实际上更安全,更容易调试。如果你认为bash有一个等价的get member(gm),那么,亲爱的先生,是你完全迷失了方向。这就是基于对象的管道与bash等文本处理管道的区别。将powershell视为automagic awk/sed的bash。Windows配置基于API;Unix是基于文本文件的。不同的工具,不同的平台,不同的方法。你最终会习惯的。手册页和公共标志-u(用法),-h(帮助),-i(非交互式),-s(脚本模式),与公共bash命令一起使用是等效的。在bash中,automatic发生在命令行标志中,熟悉bash命令意味着sed通常只需要用于处理实际文本。可以将bash看作是带有automatic类型的powershell,因此不需要严格限制的OOP管道。将bash视为基于文本的,就像查看PS管道上的原始数据,然后变得相当混乱。你
function My-Function{
& ([scriptblock]::Create('param($newInput); "Newinput is $newInput"')) $input
}
'piped1', 'piped2' | my-function