我基本上想要创建一个每次都会执行的变量。最简单的例子:
$myvar = `write-host foo`;
然后每当我引用$ myvar时,它都会输出foo:
dir $myvar
Directory of foo:
关键是每次引用$ myvar时都会重新执行write-host foo
部分
答案 0 :(得分:5)
通过创建自己的PSVariable派生类在托管代码(C#/ VB)中可行,但不是直接在纯脚本中,抱歉。我说“纯脚本”,因为在powershell v2中你可以使用add-type内联C#。也就是说,您可以依靠隐式ToString调用在脚本中破解它,但这在每种情况下都不可靠。例如:
# empty custom object
$o = new-object psobject
# override ToString with a PSScriptMethod member
$o.psobject.members.add((new-object `
System.Management.Automation.PSScriptMethod "ToString", {
"ticks: $([datetime]::now.ticks)" }))
ps> $o
ticks: 634256043148813794
ps> $o
ticks: 634256043165574752
请注意,每次评估变量时,滴答计数都不同。如果你只是使用常规函数而不是变量,那么这就容易多了。
function Ticks { [datetime]::now.ticks }
# use as a parameter - note the use of ( and )
ps> write-host (ticks)
634256043148813794
# use in a string - note the use of $( and )
ps> write-host "ticks $(ticks)"
ticks 634256043165574752
希望这有帮助
-Oisin
答案 1 :(得分:2)
另一种方法是简单地强制重新计算提示函数,以便每次完成命令并显示提示时更新变量:
$MySecretOldPromptStorage = ${Function:Prompt}
function prompt { $o = $([datetime]::now.ticks); &$MySecretOldPromptStorage }
当然,这会导致它每次运行而不是按需运行
答案 2 :(得分:2)
完成@ x0n提及的内容并不困难。我们可以在代码中嵌入一段C#并获得一个真正的自动变量:
# define a class of my variable, override the Value property
Add-Type @'
using System;
using System.Management.Automation;
public class MyVariable : PSVariable
{
public MyVariable(string name) : base(name) {}
public override object Value
{
get { return DateTime.Now.Ticks; }
set { }
}
}
'@
# install the variable
$ExecutionContext.SessionState.PSVariable.Set((New-Object MyVariable Ticks))
# test
$Ticks
sleep 1
$Ticks
sleep 1
$Ticks
关于PSVariable
:
http://msdn.microsoft.com/en-us/library/system.management.automation.psvariable