Когда bash вызывается с именем sh, он делает это :
if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
act_like_sh++;
а затем позже устанавливает POSIXLY_CORRECTпеременную оболочкиy :
if (act_like_sh)
{
bind_variable ("POSIXLY_CORRECT", "y", 0);
sv_strict_posix ("POSIXLY_CORRECT");
}
bind_variableвызовы bind_variable_internal, которые, если в это время включен атрибут оболочки a(что было бы, если бы вы вызвали оболочку -a), помечают переменную оболочки как экспортированную .
Итак, в вашем первом сценарии:
#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'
sedвызывается POSIXLY_CORRECT=yв его среде, что заставит его жаловаться [\d001-\d008]. (То же самое происходит, если sed предоставлена --posixопция.)
В ГНУ СЭД, является кодом выхода для символа которого численное значение в базе-10 NNN , но в режиме POSIX, это отключено внутри выражения кронштейна, так что , буквально означает символы , и т.д., при этом диапазон от к . В порядке кодов символов, предшествует (и диапазон включает все цифры, кроме нуля, плюс все заглавные буквы, а также некоторые специальные символы). В используемой вами локали сортирует , однако, поэтому диапазон недопустим.\dNNN[\d001-\d008]\d1\1\en_US.UTF-8\1
В вашем втором сценарии:
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
Несмотря на то, что POSIXLY_CORRECTон установлен в оболочке, он не экспортируется, поэтому sed вызывается без использования POSIXLY_CORRECTв среде, а sed запускается с расширениями GNU.
Если вы добавите export POSIXLY_CORRECTв верхней части вашего второго скрипта, вы также увидите жалобу sed.
shодинаковы. Не все sed эквивалентны. Чтоshвы используете? В какой ОС? и какой сед (возможно?sed --versionесли не подведет)?