批次檔執行單行 PowerShell 指令之內嵌雙引號字元處理
0 |
想將 "TIME:$(Get-Date -Format HH:mm)" | Add-Content "$(Get-Date -Format yyyyMMdd).txt"
當成 PowerShell.exe -Command 參數放在 .bat 檔執行,卡了老半天。
直接寫 powershell -Command "TIME:$(Get-Date -Format HH:mm)" | Add-Content "$(Get-Date -Format yyyyMMdd).txt"
會解析錯誤,CMD 會拆成 powershell Get-Date -Format HH:mm
串接 Add-Cotent ...
,而 Add-Content 非有效 CMD 指令,會噴出「不是內部或外部命令錯誤、可執行的程式或批次檔」訊息。
前後加上雙引號當成字串參數傳入,原本的 " 依 CMD 慣例要跳脫成 "",依理會寫成 powershell -Command "& {""TIME:$(Get-Date -Format HH:mm)"" | Add-Content ""$(Get-Date -Format yyyyMMdd).txt""}"
,但卻得到「字串遺漏結尾字元:"」錯誤,胡亂將 "" 改成 PowerShell 內跳脫字元也不對:
註:寫成 Inline Script Block 時要加 & 參考
沒在官方文件查到相關說明,最後是在 Stackoverflow 查到一篇超詳細的批次檔雙引號跳脫大全,完整收錄在 CMD、Bash、PowerShell CLI 的雙引號處理方式。在 Calling PowerShell's CLI from cmd.exe or POSIX-like shells 一節提到:
""
寫法在 CMD 或批次呼叫 Windows PowerShell 時會出現字串遺漏結尾字元:" / error "The string is missing the terminator"
錯誤 (就是我遇到的狀況),但 PowerShell [Core] v6+ 沒問題。\"
或"""
基本上可行,但不保險,像是遇到&
時會解析錯誤,必須也改成^&
:
\""
可以,但缺點是連續空白會被壓縮(類似 HTML 處理連續空白的行為):(# 到 Q&A 間的七個空白只算一個)
"^""
(是,你沒看錯,要四個符號) 是 Windows PowerShell 的最佳解,PowerShell [Core] v7+ 則可用""
- 若在 Unix-like 平台 (macOS、Linux),只能用 PowerShell Core - pwsh,請一律使用
\"
即可,或是最外層包字串的雙引號改用單引號:
題外話,為了要實測 Linux 跑 PowerShell v7,趁此機會試了在 Debian 上安裝 PowerShell,照著官方文件 在 Debian Linux 上安裝 PowerShell 不用一分鐘裝完,熟悉的 Get-Process 指令搬到 Linux 也能跑,看到的則是 Linux 上正在運行的程序,酷!
最後小試一下,載入 NuGet 程式庫(.NET Standard/.NET Core 版),在 Linux 要用 PowerShell 產生 QRCode 也是小菜一碟。
註:在 PowerShell 要引用巢狀類別,不是用 . ,而是要寫成 +,如下圖的 [Net.Codecrete.QrCodeGenerator.QrCode+Ecc]::Medium
未來在 Linux 除了 Bash,又多一個寫 Shell 腳本的選擇。
Tips of the correct way to escape double quotation marks when calling PowerShell in shell/batch.
Comments
Be the first to post a comment