我想知道是否有人可以幫助我理解為什么System.IO.FileInfo在處理相對路徑時在 Windows 上的行為與在 Linux 上不同。
例子
- 在 Linux 上
PS /home/user/Documents> ([System.IO.FileInfo]'./test.txt').FullName
/home/user/Documents/test.txt
- 在 Windows 上
PS C:\Users\User\Documents> ([System.IO.FileInfo]'.\test.txt').FullName
C:\Users\User\test.txt
編輯
為了澄清上述內容,System.IO.FileInfo在 Windows 或 Linux上處理相對路徑的方式沒有區別。該問題與[System.IO.Directory]::GetCurrentDirectory()未被Push-Location或更新有關Set-Location。
一個簡單的例子:
PS /home/user> [System.IO.Directory]::GetCurrentDirectory()
/home/user
PS /home/user> cd ./Documents/
PS /home/user/Documents> [System.IO.Directory]::GetCurrentDirectory()
/home/user
假設這是一種預期的行為,那么param(...)在腳本和函式上接近我們的塊以接受兩種情況(絕對和相對)的最佳方式是什么。我曾經將路徑引數約束為輸入,System.IO.FileInfo但現在我可以看到它顯然是錯誤的。
這是我遇到的,但我想知道是否有更好的方法。
我相信Split-Path -IsAbsolute如果使用網路路徑也會帶來問題,如果我錯了,請糾正我。
param(
[ValidateScript({
if(Test-Path $_ -PathType Leaf) {
return $true
}
throw 'Invalid File Path'
})]
[string]$Path
)
if(-not(Split-Path $Path -IsAbsolute))
{
[string]$Path = Resolve-Path $Path
}
以下應該能夠處理:
- UNC 路徑
- 在 Windows 和 Linux 上作業
- 高效
- 處理相對路徑
從$Path有效的基數開始ValidateScript attribute,我們只需要確定我們正在處理的路徑是 UNC、Relative 還是 Absolute。
UNC 路徑必須始終是完全限定的。它們可以包含相對目錄段(. 和 ..),但它們必須是完全限定路徑的一部分。您只能通過將 UNC 路徑映射到驅動器號來使用相對路徑。
We can assume a UNC path must always start with \\, so this condition should suffice to determine if $Path will be manipulated or not:
if(-not $Path.StartsWith('\\'))
Lastly, in the begin block, updating the environment's current directory each time our script or function runs with:
[Environment]::CurrentDirectory = $pwd.ProviderPath
By doing so, ([System.IO.FileInfo]$Path).FullName should give us the absolute path of our parameter, be it UNC, Relative or Absolute.
param(
[ValidateScript({
if(Test-Path $_ -PathType Leaf) {
return $true
}
throw 'Invalid File Path'
})] [string]$Path
)
begin
{
[Environment]::CurrentDirectory = $pwd.ProviderPath
}
process
{
if(-not $Path.StartsWith('\\'))
{
$Path = ([System.IO.FileInfo]$Path).FullName
}
$Path # => Should be Absolute
}
uj5u.com熱心網友回復:
感覺有點重復,但既然你問了..
對不起,我不了解 Linux,但在 Windows 中:
您可以先添加一個測驗以查看路徑是否是相對的,如果是,則將其轉換為絕對路徑,例如:
$Path = '.\test.txt'
if (![System.IO.Path]::IsPathRooted($Path) -or $Path -match '^\\[^\\] ') {
$Path = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($pwd, $Path))
}
我還添加了$Path -match '^\\[^\\] '以反斜杠開頭的相對路徑,例如\ReadWays.ps1表示路徑從根目錄開始。以兩個反斜杠開頭的 UNC 路徑被視為絕對路徑。
顯然(我真的不知道為什么......)以上在 Linux 上不起作用,因為在那里,當使用 UNC 路徑時,該部分會![System.IO.Path]::IsPathRooted('\\server\folder')產生True.
看來您需要先檢查作業系統,然后在 Linux 上進行不同的檢查。
$Path = '\\server\share'
if ($IsWindows) { # $IsWindows exists in version 7.x. Older versions do `$env:OS -match 'Windows'`
if (![System.IO.Path]::IsPathRooted($Path) -or $Path -match '^\\[^\\] ') {
$Path = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($pwd, $Path))
}
}
else {
if ($Path -notlike '\\*\*') { # exclude UNC paths as they are not relative
if (![System.IO.Path]::IsPathRooted($Path) -or $Path -match '^\\[^\\] ') {
$Path = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($pwd, $Path))
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/376426.html
標籤:powershell system.io.fileinfo
上一篇:如何在回圈中驗證用戶輸入?
