POSIX shell 註釋與續行
編輯以澄清我的問題:
POSIX 說:
如果 <newline> 跟在(未加引號的)<backslash> 之後,shell 應將其解釋為行繼續。<backslash> 和 <newline> 應在將輸入拆分為標記之前刪除。
然而,
dash
或其他實現,首先標記化輸入。結果,\<newline>
不被辨識而是# this is a comment \
被丟棄。這種行為是否符合 POSIX?同樣,POSIX 說在標記化之前應刪除行繼續。下面的過程真的不符合 POSIX 嗎?
- 閱讀整個輸入:
"echo hello ... \<newline> ... bye"
- 搜尋未引用
\<newline>
並刪除它們:"echo hello ... bye"
- 標記化:標記化:
"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
這是因為 # 之後的所有內容都被視為註釋,並且 \ 之前的所有內容都被丟棄,因此 <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
#
,則它和直到(但不包括)下一個的所有後續字元<newline>
都應作為註釋被丟棄。結束行的<newline>
不被視為註釋的一部分。您引用的標準部分,即引用部分,表示當遇到前面有反斜杠的換行符時……
<backslash>
未引用的 A應保留以下字元的文字值,但 a 除外<newline>
。如果 a<newline>
跟在<backslash>
之後,shell 應將其解釋為行繼續。在將輸入拆分為標記之前<backslash>
,<newline>
應刪除 and。$$ … $$
請注意,在掃描器實際遇到未引用的反斜杠之前,這不會生效,該反斜杠由令牌辨識過程處理:
如果目前字元是
<backslash>
、單引號或雙引號並且它沒有被引用,它將影響到引用文本末尾的後續字元的引用。引用規則如“引用”中所述。正如這個答案中已經提到的,掃描器將首先遇到註釋字元,然後再看到反斜杠,這將觸發處理該行其餘部分(包括任何引用字元)作為註釋的令牌辨識規則。因此,行尾換行的引用永遠不會生效。