Shell-Script

為什麼 -a in ‘#!/bin/sh -a’ 影響 sed 而 ‘set -a’ 不影響?

  • August 13, 2018

如果我執行以下 .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_CORRECTshell 變數設置為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在其環境中呼叫 with POSIXLY_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 抱怨。

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