powershell - 如何使用 PowerShell cmdlet 对 PowerShell 脚本文件进行完整的语法检查
问题描述
我正在编写一个控制台应用程序来验证 PowerShell 脚本语法。我的要求是在不执行脚本的情况下验证 PowerShell 脚本。我在 PowerShell 命令下面发现了这个,它可以在不执行脚本的情况下执行语法检查。
Get-Command -syntax 'D:\powershell\deleteDemoFile.ps1'
但是,我发现它没有进行完整的语法检查。例如,在没有声明的情况下在 PowerShell 中使用了一个变量,或者它们是(函数、if、ForEach 等)中的拼写错误,上述命令不会捕获此类语法错误。
下面是 PowerShell 脚本文件 (.\deleteDemoFile.ps1) 的示例代码 请注意,在下面的代码中 (if, Function) 的拼写错误,并且使用了变量“$log_dir”但未声明。
当我运行 PowerShell 命令时Get-Command -syntax 'D:\powershell\deleteDemoFile.ps1'
,该命令不会引发任何语法错误。
Write-Host "Hello, World!"
ifTypo(-not (test-path -path $log_dir )) {
new-item -itemtype directory -path $log_dir
}
FunctionTypo log {
Param ([string]$log_string)
write-host $log_string
add-content $log_file -value $log_string
}
log("Deleting a demo txt file")
# PowerShell -WhatIf safety parameter
Clear-Host
Get-Childitem D:\powershell\SomeFile\demo.txt -Recurse | Remove-Item
所以我想知道。
- 这个 PowerShell 命令执行语法检查的效率如何?
- 它是否仅验证 PowerShell cmdlet、函数和别名的语法?
- 此命令与哪个版本的 PowerShell 脚本兼容?
是否有任何其他命令可以执行完整的语法检查?
以下是 PowerShell 命令的参考:https ://stackoverflow.com/a/55337824/3725706
解决方案
请注意,Get-Command
's -Syntax
switch 的目的是显示命令的语法图,即显示其参数及其类型,即如何调用它。
由于发现脚本的此信息需要解析它们,因此作为副作用,您确实会检测到语法错误[1](Get-Command
然后调用失败并报告遇到的特定语法错误)。
但是,您的示例脚本不包含语法错误:虽然它在执行时不会执行您想要的操作,但它在语法上是有效的:
ifTypo
并且FunctionTypo
被解释为命令名称,而不是拼写错误的关键字。- 因此,您只会在 execution 上看到问题,例如,当尝试调用名为 的命令(cmdlet、函数、脚本、别名、可执行文件)
ifTypo
时。
- 因此,您只会在 execution 上看到问题,例如,当尝试调用名为 的命令(cmdlet、函数、脚本、别名、可执行文件)
有关PowerShell 的两种基本解析模式、参数模式(如 shell)和表达式模式(如编程语言)的信息,请参阅概念about_Parsing帮助主题。
iRon建议的Invoke-ScriptAnalyzer
cmdlet(PSScriptAnalyzer
您可以安装的模块的一部分) ,也用于 Visual Studio Code 的 PowerShell 扩展以进行设计时分析,可能能够指出潜在的其他问题,但在手头的情况下它不会(它只警告不要在你的脚本中使用)。Install-Module PSScriptAnalyzer
Write-Host
笔记:
PowerShell 的两种解析模式总是相当宽松的语法,一般来说,动态语言中的静态分析只能做这么多。
没有现有功能可以检测到您的脚本存在的问题;一个潜在的解决方案是通过在项目的 GitHub 存储库中打开一个问题来要求添加标记潜在关键字拼写错误的新规则,但请注意,这些规则最终是猜测,因为看起来像拼写错误的关键字可能是合法的命令名称.
Invoke-ScriptAnalyzer
[1] 实际上,Get-Command -Syntax
间接调用官方 PowerShell 解析器以查找语法错误的便捷快捷方式,这需要更多的努力 - 请参阅此答案。
推荐阅读
- c# - Azure 媒体服务 V3 元数据
- xpath - 有没有办法从部分搜索中获取完整的属性名称,并将其保存为变量?
- c++ - CGAL seam_mesh:如何在边界的 halfedge_descriptor 中包含接缝?
- spring-webflux - 如何根据反应堆上下文更改 url webClient
- c++ - 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- symfony - 教义:迁移:迁移。元数据存储不是最新的,请运行 sync-metadata-storage 命令修复此问题
- swift - 在 SwiftUI 中禁用模态表拖动手势
- c# - 查找 C Sharp 应用程序的入口点
- javascript - 匹配特定的 url 参数并返回其值
- java - JAVA - 类似运算符