Re: [心得] PowerShell 那些惱人的路徑 BUG

作者: falcon (falken)   2024-09-28 07:47:00
: hunandy14: 其實真實的情況是 pwsh 社群決議改掉預設萬用了
: hunandy14: 他不是bug就是當初設計 不符合直覺
: hunandy14: 所以應該不會修了,那是式樣不是bug
: hunandy14: 測試結果確實沒有bug存在,只是惱人的設計
bug 是指對於萬元字元路徑的跳脫處理有誤
預設萬元字元我只當它是反人類設計而已
https://github.com/PowerShell/PowerShell/issues/7999
主要是講這 bug 的影響
順便提了兩句微軟的雞婆的
設計導致多餘的困擾,不是本篇的重點
由於 -like 運算子跟 cmdlet 的路徑參數
對於萬用字元的解讀不同
這兩者都是 PowerShell 原生的功能
對於同樣的東西應該有相同行為
所以說,在這問題上最多只能有一方是正確的
https://i.imgur.com/YiXffzL.png
如過這是特性不是 bug 的話
那工作目錄中的特殊字元應該要做獨特的跳脫處理
畢竟這是在 cmdlet 內部處理的
不應該發生錯誤
Set-Location -LiteralPath 'D:\test`[0-2]'
Resolve-Path -Path .
Resolve-Path -LiteralPath .
使用 -Path . 與使用 -LiteralPath .
前者在任何版本都會發生錯誤
則只有在新的跨平台版 PS 才能得到正確路徑
https://i.imgur.com/m5uoXdF.png
另外,我不是說管線那設計是 bug
bug 是指在這個工作目錄把程式作為命令執行
會因為因為工作目錄路徑導致異常行為
https://i.imgur.com/mbG9jTo.png
Start-Process 有 -WorkingDirectory 可以用
它會直接拿你跳脫處理過的路徑當 base 去組出完整路徑
就能避開對於工作目錄路徑本身包含 ` 時的問題
而 System.Diagnostics.Process 不是 PS 的 cmdlet 所以沒此問題
拿 Start-Process 舉例,只因為它是 PowerShell 的 Cmdlet
作者: hunandy14 (Charlott.HonG)   2024-09-28 23:00:00
圖1並不是因為解讀不同導致的,而是路徑相關的cmdlet會多做一次雙引號的解釋,這個估計是三張圖的bug根源多做一次雙引號用說的可能不好解釋,放張圖給你看" target="_blank" rel="noreferrer noopener nofollow">
這個邏輯雖然無誤,但是就是個反人類設計圖3估計是這個設計實際引發的bug...到圖2圖3這一步,明顯是這個設計導致的bug了摁...我認為是bug了,太腦殘了這圖中的檔案真實路徑是 "D:\test\Test`[1].txt"
作者: falcon (falken)   2024-09-29 00:09:00
網路上都找好久,都沒有比較全面的方案,也只能自己動手了對了,如果是 te`st`[0].txt 呢?數字部分一樣用萬用字元我試過兩倍量 ` 不管用…感覺要改成正規表示法才可靠了
作者: hunandy14 (Charlott.HonG)   2024-09-29 12:02:00
是這樣解的 https://i.imgur.com/5E7eKjs.png我猜你應該快摸到他的邏輯了,就是解2次雙引號八成是為了區別那括號到底是字串還是萬用字元寫一個依照萬用字元表添加反引號的函式或許能解圖2應該是吃了這個虧導致的,官方cmdlet自己出bug
作者: smallreader (小讀者)   2024-09-29 13:36:00
高手過招(眼花撩亂ing
作者: hunandy14 (Charlott.HonG)   2024-09-29 14:07:00
試了一下 Resolve-Path 應該無解。改用GetFullPath吧" target="_blank" rel="noreferrer noopener nofollow">
作者: falcon (falken)   2024-09-29 15:06:00
這樣看起來,如果以cmdlet的處理方式為準的話-like 運算子反而才是壞的,他的行為更不規律-like能夠同時符合一般的跳脫規則,與cmdlet獨特的規則麻煩了,不知道要按一般邏輯處理跳脫,還是照這反智規則看來只能按照一般的規則,將萬用字元模式轉成正規表示法還需要一個參數來決定要不要先把輸入的萬元字元中的``取代為單個`,這樣就能在兩種規則中切換
作者: hunandy14 (Charlott.HonG)   2024-10-09 14:23:00
今天閒著把github上的討論串都看了 2018就有了...一個可以不用自己處理邏輯的解法是這樣的https://i.imgur.com/A17ieJi.png不過這有效範圍只有到父資料夾名稱
作者: falcon (falken)   2024-10-09 18:04:00
我目前是將萬用字元路徑轉成正規表示法,遞迴方法一層用-match運算子比對名稱。結果100%可靠。但效率就不高了,遞迴方法只能停止從不正確的子目錄繼續往下尋找路徑,但也要先比對過所有子目錄名稱,才會知道要從哪個目錄往下走這能處理任何一層目錄名稱中的*或?的多重符合https://i.imgur.com/ZABP3w3.png
作者: hunandy14 (Charlott.HonG)   2024-10-09 23:04:00
我一開始有想過轉發,只是也不知道如何實現就算參數能實現還有個大魔王管道沒找到可靠的方法估計也只能取捨了然後就是這應該不是完全解,不然這事不會拖6年還沒解

Links booklink

Contact Us: admin [ a t ] ucptt.com