Shell-Script
為什麼 -a in ‘#!/bin/sh -a’ 影響 sed 而 ‘set -a’ 不影響?
如果我執行以下 .sh 文件:
#!/bin/sh -a echo "a" | sed -e 's/[\d001-\d008]//g'
結果是一個錯誤:
sed: -e 表達式 #1, char 18: 無效的範圍結束
但是,如果我執行以下 .sh 文件:
#!/bin/sh set -a echo "a" | sed -e 's/[\d001-\d008]//g'
它執行沒有錯誤。第二個程式碼不應該與第一個程式碼等效嗎?為什麼第一個錯誤?
當使用 name 呼叫 bash 時
sh
,它會執行以下操作:if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0') act_like_sh++;
然後將
POSIXLY_CORRECT
shell 變數設置為y
:if (act_like_sh) { bind_variable ("POSIXLY_CORRECT", "y", 0); sv_strict_posix ("POSIXLY_CORRECT"); }
bind_variable
呼叫bind_variable_internal
,如果 shell 屬性a
當時是打開的(如果你用 呼叫 shell 會是這樣-a
),將 shell 變數標記為export。所以在你的第一個腳本中:
#!/bin/sh -a echo "a" | sed -e 's/[\d001-\d008]//g'
sed
在其環境中呼叫 withPOSIXLY_CORRECT=y
,這將使它抱怨[\d001-\d008]
. (如果給 sed--posix
選項,也會發生同樣的事情。)在 GNU sed 中,是以 10 為基數的數值為NNN的字元的轉義碼,但在 POSIX 模式下,在括號表達式內禁用此功能,因此, 字面意思是字元,等,範圍為到. 按照字元程式碼的順序,在前面(範圍包括除零以外的所有數字,加上所有大寫字母,加上一些特殊字元)。但是,在您使用的語言環境中,排序在 之前,因此範圍無效。
\d*NNN*``[\d001-\d008]``\``d``1``\``1``\``en_US.UTF-8``\``1
在您的第二個腳本中:
#!/bin/sh set -a echo "a" | sed -e 's/[\d001-\d008]//g'
即使
POSIXLY_CORRECT
在 shell 中設置,它也不會被導出,因此 sedPOSIXLY_CORRECT
在環境中被呼叫,並且 sed 使用 GNU 擴展執行。如果您
export POSIXLY_CORRECT
在第二個腳本的頂部附近添加,您還會看到 sed 抱怨。