Bash
為什麼 dash 的 echo 擴展 與 bash 的 echo 不同?
我有一個小的開源項目,出於各種原因,我嘗試用可移植的 shell 腳本編寫。它的自動化集成測試檢查路徑表達式中的敵對字元是否得到正確處理等。
/bin/sh
提供的使用者bash
在測試中看到失敗,我已簡化為以下內容:echo "A bug\\'s life" echo "A bug\\\\'s life"
在 bash 上,它會產生以下預期結果:
A bug\'s life A bug\\'s life
使用我開發的破折號,它可以做到這一點:
A bug\'s life A bug\'s life
我想認為我沒有在 dash 中發現錯誤,我可能會遺漏一些東西。對此有合理的解釋嗎?
在
echo "A bug\\'s life"
因為它們是雙引號,並且
\
在雙引號內是特殊的,所以第一個\
被shell理解為轉義/引用第二個\
。所以一個A bug\'s life
參數被傳遞給echo
.echo "A bug\'s life"
本來可以達到完全一樣的。
'
在雙引號內沒有特殊性,\
不會刪除,因此它與傳遞給的參數完全相同echo
。正如為什麼 printf 比 echo 更好?,實現之間有很多變化
echo
。在符合 UNIX 的實現中,如
dash
’echo
內置¹,\
用於引入轉義序列:\n
換行符、\b
退格符、\0123
八進制序列……以及\\
反斜杠本身。一些(非POSIX)需要一個
-e
選項,或者僅在一致性模式下才這樣做(例如,當使用OS / Xbash
等正確選項建構時或在環境中呼叫時)。sh``SHELLOPTS=xpg_echo
所以在標準(僅 Unix 標準;POSIX 未指定行為)
echo
中,echo '\\'
如同:
echo "\\\\"
輸出一個反斜杠,而
bash
不是在一致性模式下:echo '\\'
將輸出兩個反斜杠。
最好避免
echo
並printf
改用:$ printf '%s\n' "A bug\'s life" A bug\'s life
在這種情況下,在所有
printf
實現中都一樣。¹
dash
’secho
在這方面是合規的,但在echo -n
UNIX 規範(POSIX + XSI)要求它輸出時不輸出任何內容-n<newline>
。