Shell

POSIX shell 註釋與續行

  • May 20, 2022

編輯以澄清我的問題:

POSIX 說:

如果 <newline> 跟在(未加引號的)<backslash> 之後,shell 應將其解釋為行繼續。<backslash> 和 <newline> 應在將輸入拆分為標記之前刪除。

然而,dash或其他實現,首先標記化輸入。結果,\&lt;newline&gt;不被辨識而是# this is a comment \被丟棄。這種行為是否符合 POSIX?同樣,POSIX 說在標記化之前應刪除行繼續

下面的過程真的不符合 POSIX 嗎?

  1. 閱讀整個輸入:"echo hello ... \&lt;newline&gt; ... bye"
  2. 搜尋未引用\&lt;newline&gt;並刪除它們:"echo hello ... bye"
  3. 標記化:標記化:"echo"(discard ' ')"hello"(discard ' ')(discard "# ... bye")

在帶有 dash-0.5.10.2-6 sh (dash) 的 Ubuntu 上,我們得到以下資訊

$ cat /var/tmp/test.sh
echo hello # this is a comment \
echo bye

$ sh /var/tmp/test.sh
hello
bye

這是因為 # 之後的所有內容都被視為註釋,並且 \ 之前的所有內容都被丟棄,因此 &lt;newline> 的行繼續不起作用。

但是,POSIX“轉義字元(反斜杠)”部分指出

<backslash> 和 <newline> 應在將輸入拆分為標記之前刪除。

並且由於# 的註釋處理是在標記化中完成的

echo hello # this is a comment \
echo bye

應該相當於

echo hello # this is a comment echo bye

這是否意味著 sh 不符合 POSIX 標準?或者在這種情況下,評論優先於行延續是否有一些理由?

如Token Recognition部分所述,shell 的輸入被逐字元掃描以將其劃分為令牌。

$$ … $$shell 應通過將下面的第一個適用規則應用於其輸入中的下一個字元,將其輸入分解為標記。

引用作為令牌辨識過程的一部分處理,但鑑於問題中的範例,shell 將遇到#引用的換行符之前的。

當 shell 在掃描輸入行期間到達未引用的註釋字元時,該行的其餘部分,包括最後的反斜杠,將作為註釋丟棄:

如果目前字元是 a #,則它和直到(但不包括)下一個的所有後續字元&lt;newline&gt;都應作為註釋被丟棄。結束行的&lt;newline&gt;不被視為註釋的一部分。


您引用的標準部分,即引用部分,表示當遇到前面有反斜杠的換行符時……

&lt;backslash&gt;未引用的 A應保留以下字元的文字值,但 a 除外&lt;newline&gt;。如果 a&lt;newline&gt;跟在&lt;backslash&gt;之後,shell 應將其解釋為行繼續。在將輸入拆分為標記之前&lt;backslash&gt;&lt;newline&gt;應刪除 and。

$$ … $$

請注意,在掃描器實際遇到未引用的反斜杠之前,這不會生效,該反斜杠由令牌辨識過程處理:

如果目前字元是&lt;backslash&gt;、單引號或雙引號並且它沒有被引用,它將影響到引用文本末尾的後續字元的引用。引用規則如“引用”中所述。

正如這個答案中已經提到的,掃描器將首先遇到註釋字元,然後再看到反斜杠,這將觸發處理該行其餘部分(包括任何引用字元)作為註釋的令牌辨識規則。因此,行尾換行的引用永遠不會生效。

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