如何在PowerShell中将路径参数转换为绝对路径(不切换目录)
PowerShell 获取路径参数的绝对路径(不改变当前目录)
问题说明
我写了个PowerShell脚本,需要接收一个路径参数,把它转成绝对路径后在其他命令里用,而且不能改变当前工作目录。本来以为把参数类型设成System.IO.FileInfo就能自动识别相对/绝对路径,结果发现相对路径会被解析到用户主目录,完全不符合预期:
比如脚本放在C:\bin\extract-zip.ps1,C:\bin已经加入PATH,我在C:\temp目录执行:
extract-foo foo.zip
输出却是:
C:\Users\user\foo.zip
而我想要的是C:\temp\foo.zip。
解决方案
方法1:用.NET的[System.IO.Path]::GetFullPath()
这个方法是最直接的,不管传入的是相对路径还是绝对路径,它都会基于当前Shell的工作目录解析出正确的绝对路径,而且不会改变当前目录。
修改脚本参数为string类型,然后调用这个方法:
[CmdletBinding()] Param([Parameter(Mandatory, HelpMessage="Archive Path")] [string]$path) # 转换为绝对路径 $absolutePath = [System.IO.Path]::GetFullPath($path) Write-Output $absolutePath
测试效果:
- 传入相对路径
foo.zip,输出C:\temp\foo.zip - 传入绝对路径
C:\temp\foo.zip,直接返回原路径
方法2:结合PowerShell原生Resolve-Path
Resolve-Path是PowerShell自带的cmdlet,也能解析路径,但要注意如果路径对应的文件/目录不存在,它默认会报错。可以搭配错误处理或者兜底方案:
[CmdletBinding()] Param([Parameter(Mandatory, HelpMessage="Archive Path")] [string]$path) # 尝试用Resolve-Path解析,不存在则静默跳过 $resolvedPath = Resolve-Path -Path $path -ErrorAction SilentlyContinue if ($resolvedPath) { $absolutePath = $resolvedPath.Path } else { # 文件不存在时用GetFullPath兜底解析 $absolutePath = [System.IO.Path]::GetFullPath($path) } Write-Output $absolutePath
这个方法更贴合PowerShell的使用习惯,同时兼顾了文件存在和不存在的情况。
为什么System.IO.FileInfo会出错
当把参数声明为[System.IO.FileInfo]时,PowerShell绑定参数时用的是进程的初始工作目录(默认是用户主目录),而不是你执行脚本时的Shell当前工作目录,所以相对路径会被解析到主目录里。因此建议参数用string类型,再手动转换绝对路径。
内容的提问来源于stack exchange,提问作者Garret Wilson
相关产品推荐
相关产品推荐

