【发布时间】:2014-05-13 19:56:15
【问题描述】:
这个问题类似于Passing empty arguments to executables using powershell,但我想扩展问题和答案,更好地理解“为什么”,因为它看起来像是一个 PowerShell 陷阱。
如果你加载 PSCX 并运行 echoargs(一个外部命令,即一个 exe 文件),你可以看到空字符串参数被跳过:
PS> echoargs word "two words" "" 123
Arg 0 is <word>
Arg 1 is <two words>
Arg 2 is <123>
但是如果你使用“CMD 转义”(--%) 你可以让它看起来“正确”:
PS> echoargs --% word "two words" "" 123
Arg 0 is <word>
Arg 1 is <two words>
Arg 2 is <>
Arg 3 is <123>
类似地,如果编写 PowerShell 函数,空字符串也会得到正确处理:
PS> Show-Args word "two words" "" 123
Arg 0 is <word>
Arg 1 is <two words>
Arg 2 is <>
Arg 3 is <123>
由于以下原因,这种差异对我来说似乎很重要。上面显示的示例在命令行上使用了文字空字符串,因此至少您对问题有所提示。 但是如果使用包含空字符串的变量,结果是完全相同的。这意味着必须:
- 严格监管所有输入外部命令的变量,或者
- 使用 CMD 转义 (--%) 并在该行的其余部分放弃使用任何 PowerShell 构造
- 用反引号/双引号引用外部命令的每个参数,例如
`"this`"或`"$this`"或`"`"
...否则会有坏事发生!
(@KeithHill 指出了上面的第三种解决方法,因此我将其添加到此处以保持完整性。它适用于文字或变量,因此虽然丑陋,但可能是三种解决方法中的最佳选择。)
因此,PowerShell 处理函数参数的方式与处理外部命令参数的方式不同 - 戏剧性地如此。这是 PowerShell 行为的不一致吗?如果不是,为什么不呢?
附录
作为参考,这是上面使用的 PowerShell 函数体:
function Show-Args()
{
for ($i = 0; $i -lt $args.length; $i++)
{
Write-Host ("Arg {0} is <{1}>" -f $i, $args[$i])
}
}
这是一个在 C# 中等效的 echoargs:
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < args.Length; i++)
{
System.Console.WriteLine("Arg {0} is <{1}>", i, args[i]);
}
}
}
【问题讨论】:
标签: powershell command-line executable