Bash

為什麼 dash 的 echo 擴展 與 bash 的 echo 不同?

  • August 30, 2021

我有一個小的開源項目,出於各種原因,我嘗試用可移植的 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 的實現中,如dashecho內置¹,\用於引入轉義序列:\n換行符、\b退格符、\0123八進制序列……以及\\反斜杠本身。

一些(非POSIX)需要一個-e選項,或者僅在一致性模式下才這樣做(例如,當使用OS / Xbash等正確選項建構時或在環境中呼叫時)。sh``SHELLOPTS=xpg_echo

所以在標準(僅 Unix 標準;POSIX 未指定行為)echo中,

echo '\\'

如同:

echo "\\\\"

輸出一個反斜杠,而bash不是在一致性模式下:

echo '\\'

將輸出兩個反斜杠。

最好避免echoprintf改用:

$ printf '%s\n' "A bug\'s life"
A bug\'s life

在這種情況下,在所有printf實現中都一樣。


¹ dash’secho在這方面是合規的,但在echo -nUNIX 規範(POSIX + XSI)要求它輸出時不輸出任何內容-n<newline>

引用自:https://unix.stackexchange.com/questions/321422