PowerShell:运行 变量中的可执行文件,不会将参数误认为是路径的一部分
PowerShell: Running executable in variable without misinterpetting argument as part of path
我需要在两个不同的语料库上对两个不同的程序进行基准测试,为了获得更准确的读数,我想 运行 在一个循环中进行基准测试,并获取每个基准测试的平均执行时间。为了简化自己,我编写了以下 PowerShell 函数:
Function Benchmark {
Param($progPath, $benchmarkPath, $iters=27)
$time = (Measure-Command { & "$progPath" "$benchmarkPath" }).TotalSeconds
$sum = $lowest = $highest = $time
for($i = 1; $i -lt $iters; $i++) {
$time = (Measure-Command { & "$progPath" "$benchmarkPath" }).TotalSeconds
$sum += $time
if($time -lt $lowest) { $lowest = $time }
elseif($time -gt $highest) {$highest = $time }
}
$sum -= ($lowest + $highest)
$sum / ($iters - 2)
}
理论上,这应该执行 $progPath
中作为命令提供的程序,并以 $benchmarkPath
中的基准测试脚本作为其参数,但是当我 运行 它像这样时,我得到以下结果:
PS > $nonPrivateBenchmark = Benchmark(".\Python\PCbuild\amd64\python", ".\Benchmarks\non_private_access.py")
& : The term '.\Python\PCbuild\amd64\python .\Benchmarks\non_private_access.py' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:3 char:30
+ $time = (Measure-Command { & "$progPath" "$benchmarkPath" }).TotalSeconds
+ ~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (.\Python\PCbuil...ivate_access.py:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
(加上第 6 行重复 26 次相同的错误。)
但是,如果分配三个参数参数并将剩余的函数体直接复制到 PowerShell 中,它将起作用并将 $nonPrivateAccess
设置为合理的值:
$progPath = ".\Python\PCbuild\amd64\python"
$benchmarkPath = ".\Benchmarks\non_private_access.py"
$iters = 27
$time = (Measure-Command { & "$progPath" "$benchmarkPath" }).TotalSeconds
$sum = $lowest = $highest = $time
for($i = 1; $i -lt $iters; $i++) {
$time = (Measure-Command { & "$progPath" "$benchmarkPath" }).TotalSeconds
$sum += $time
if($time -lt $lowest) { $lowest = $time }
elseif($time -gt $highest) {$highest = $time }
}
$sum -= ($lowest + $highest)
$nonPrivateBenchmark = $sum / ($iters - 2)
我通过实验得出结论,问题是 "$progPath" "$benchmarkPath"
在使用 &
运算符执行之前连接成单个字符串 '.\Python\PCbuild\amd64\python .\Benchmarks\non_private_access.py'
,并且 space 分隔它们被解释为命令名称的一部分,使 PowerShell 尝试将整个字符串作为单个命令执行(无法执行)。我曾尝试在参数参数周围和内部放置转义引号,但无济于事。还有其他人可以解决这个问题吗?
PS:
相当广泛的搜索只给了我很多有相反问题的人的点击率。会不会是我激活了一些非默认的 PowerShell 设置,导致它过于激进地解析 space?
Benchmark(".\Python\PCbuild\amd64\python", ".\Benchmarks\non_private_access.py")
此语法将数组传递给基准函数的第一个参数,然后在用作命令时将其转换为单个字符串。这实际上等同于:
Benchmark ".\Python\PCbuild\amd64\python", ".\Benchmarks\non_private_access.py"
将多个参数传递给 PowerShell 函数的正常语法是在参数之间放置一个 space:
Benchmark ".\Python\PCbuild\amd64\python" ".\Benchmarks\non_private_access.py"
您还可以使用参数名称:
Benchmark -progPath ".\Python\PCbuild\amd64\python" -benchmarkPath ".\Benchmarks\non_private_access.py"
我需要在两个不同的语料库上对两个不同的程序进行基准测试,为了获得更准确的读数,我想 运行 在一个循环中进行基准测试,并获取每个基准测试的平均执行时间。为了简化自己,我编写了以下 PowerShell 函数:
Function Benchmark {
Param($progPath, $benchmarkPath, $iters=27)
$time = (Measure-Command { & "$progPath" "$benchmarkPath" }).TotalSeconds
$sum = $lowest = $highest = $time
for($i = 1; $i -lt $iters; $i++) {
$time = (Measure-Command { & "$progPath" "$benchmarkPath" }).TotalSeconds
$sum += $time
if($time -lt $lowest) { $lowest = $time }
elseif($time -gt $highest) {$highest = $time }
}
$sum -= ($lowest + $highest)
$sum / ($iters - 2)
}
理论上,这应该执行 $progPath
中作为命令提供的程序,并以 $benchmarkPath
中的基准测试脚本作为其参数,但是当我 运行 它像这样时,我得到以下结果:
PS > $nonPrivateBenchmark = Benchmark(".\Python\PCbuild\amd64\python", ".\Benchmarks\non_private_access.py")
& : The term '.\Python\PCbuild\amd64\python .\Benchmarks\non_private_access.py' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:3 char:30
+ $time = (Measure-Command { & "$progPath" "$benchmarkPath" }).TotalSeconds
+ ~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (.\Python\PCbuil...ivate_access.py:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
(加上第 6 行重复 26 次相同的错误。)
但是,如果分配三个参数参数并将剩余的函数体直接复制到 PowerShell 中,它将起作用并将 $nonPrivateAccess
设置为合理的值:
$progPath = ".\Python\PCbuild\amd64\python"
$benchmarkPath = ".\Benchmarks\non_private_access.py"
$iters = 27
$time = (Measure-Command { & "$progPath" "$benchmarkPath" }).TotalSeconds
$sum = $lowest = $highest = $time
for($i = 1; $i -lt $iters; $i++) {
$time = (Measure-Command { & "$progPath" "$benchmarkPath" }).TotalSeconds
$sum += $time
if($time -lt $lowest) { $lowest = $time }
elseif($time -gt $highest) {$highest = $time }
}
$sum -= ($lowest + $highest)
$nonPrivateBenchmark = $sum / ($iters - 2)
我通过实验得出结论,问题是 "$progPath" "$benchmarkPath"
在使用 &
运算符执行之前连接成单个字符串 '.\Python\PCbuild\amd64\python .\Benchmarks\non_private_access.py'
,并且 space 分隔它们被解释为命令名称的一部分,使 PowerShell 尝试将整个字符串作为单个命令执行(无法执行)。我曾尝试在参数参数周围和内部放置转义引号,但无济于事。还有其他人可以解决这个问题吗?
PS: 相当广泛的搜索只给了我很多有相反问题的人的点击率。会不会是我激活了一些非默认的 PowerShell 设置,导致它过于激进地解析 space?
Benchmark(".\Python\PCbuild\amd64\python", ".\Benchmarks\non_private_access.py")
此语法将数组传递给基准函数的第一个参数,然后在用作命令时将其转换为单个字符串。这实际上等同于:
Benchmark ".\Python\PCbuild\amd64\python", ".\Benchmarks\non_private_access.py"
将多个参数传递给 PowerShell 函数的正常语法是在参数之间放置一个 space:
Benchmark ".\Python\PCbuild\amd64\python" ".\Benchmarks\non_private_access.py"
您还可以使用参数名称:
Benchmark -progPath ".\Python\PCbuild\amd64\python" -benchmarkPath ".\Benchmarks\non_private_access.py"