visit http://blogs.oracle.com/vaibhav/entry/not_as_easy_as_we, see 3rd reply.
例子代码:
String cmdLine = "powershell -file \""+this.scriptPath+"\" get-performance";
Process ps = Runtime.getRuntime().exec("powershell -file C:/eclipse/test.ps1");
ps.getOutputStream().close(); // It seems that powershell first reads all input from it's input stream before going.
String rs = "", line;
BufferedReader rd = new BufferedReader(new InputStreamReader(ps.getInputStream()));
try{
while((line = rd.readLine()) != null){
rs += line;
}
}finally{
rd.close();
}
System.out.println(rs);
在python中用了subprocess模块调用,没发现此问题。
很简单,invoke-expression,“&”符号都可以,但是“&”有些限制,例子代码如下:
$a = "get-process"
&$a ## or & $a 有无空格均可,不过此种用法有限制,只能将$a内部的字符串解释为可以识别的cmdlet,不支持类似于"get-process -id xxx"这种带参数的形式,不过带参数的写法可以用如下形式实现:
&$a -id xxx ## 在字符串外部实现
invoke-expression相当于python or javascript中的eval,用于把字符串当做脚本执行,简单例子如下:
$foo = 2
Invoke-Expression '$foo +=2'
注意用单引号,否则字符串中的变量会先被解释成值,就变成2 +=2了。
关于各种语言中eval或与之等价操作的介绍,请参见:http://en.wikipedia.org/wiki/Eval
$h = @{"b"=1}
$a = @(1, 3, 4)
Write-Host "value: $($h.b)"
Write-Host "value:$($a[0])"
在字符串中的"$"用于获取变量的值并转化成字符串,上面的例子如果写成Write-Host "value: $h.b",输出则为"value: System.Collections.Hashtable.b",因为只对$h求值($h的字符串值为"System.Collections.Hashtable");而写成$($h.b),先对$h求值,然后外边的$再对$h中key为"b"的键求值,才会获得正确的结果:"value: 1"。
延伸思考:如果数组或者Hashtable嵌套多层的情况下,可以用多个"$"按照嵌套顺序求值即可,继续上面的例子:
$h.array = $a
Write-Host "value: $($($h.array)[2])" ## result is "value: 4"
Set-StrictMode -version latest
foreach($obj in $objs)
如果$objs = $null,会进入foreach体内,这时$obj也是空值,执行一遍foreach块内代码后退出foreach
如果$objs = @(),则会略过foreach
又研究了下管道中的where,和foreach情况类似,看下面code:
$b = $a | where{$_.name -eq "xxx"}
如果$a = @(),$b则为$null;如果$a = $null则会进入where里面,最后报异常说没有“name”这个属性,看来对于foreach和where,输入只区分为数组和非数组2种类型,对于数组,顺序取里面的元素处理;对于非数组,则把它当做只有一个元素的数组对待。
function foo()
{
return @()
}
这时如果你用上面第4个问题中的foreach处理的话,就会有问题;但是如果是@{},则不会有这种情况。
想到一个可能的原因是因为powershell底层实现使用.net,@()应该是使用了.net语言内置的数组结构,而@{}是使用库中的hashtable对象实现的,可能是这点的不同造成了这个现象。