Kiedy bash jest wywoływany z nazwą sh
, robi to :
if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
act_like_sh++;
a następnie ustawia POSIXLY_CORRECT
zmienną powłoki nay
:
if (act_like_sh)
{
bind_variable ("POSIXLY_CORRECT", "y", 0);
sv_strict_posix ("POSIXLY_CORRECT");
}
bind_variable
wywołań bind_variable_internal
, które, jeśli atrybut powłoki a
jest w tym czasie włączony (tak jak byłoby w przypadku wywołania powłoki -a
), oznaczają zmienną powłoki jako wyeksportowaną .
Więc w twoim pierwszym skrypcie:
#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'
sed
jest wywoływane POSIXLY_CORRECT=y
w jego środowisku, co spowoduje, że narzeka [\d001-\d008]
. (To samo dzieje się, jeśli podano --posix
opcję sed .)
W GNU sed, jest kodem ucieczki dla znaku, którego wartością liczbową w bazie-10 jest NNN , ale w trybie POSIX jest on wyłączony w wyrażeniu nawiasowym, więc\dNNN
[\d001-\d008]
, dosłownie oznacza postacie \
, d
itp, przy czym zakres wynosi od 1
do \
. W kolejności kodów znaków 1
występuje przed \
(a zakres obejmuje wszystkie cyfry oprócz zera, plus wszystkie duże litery oraz niektóre znaki specjalne). Jednak w en_US.UTF-8
ustawieniach regionalnych, których używasz, \
sortuje się wcześniej 1
, więc zakres jest nieprawidłowy.
W twoim drugim skrypcie:
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
nawet jeśli POSIXLY_CORRECT
jest ustawiony w powłoce, nie jest eksportowany, więc sed jest wywoływany bez POSIXLY_CORRECT
w środowisku, a sed działa z rozszerzeniami GNU.
Jeśli dodasz export POSIXLY_CORRECT
w górnej części drugiego skryptu, zobaczysz również, że narzeka.
sh
są takie same. Ani wszystkie sed nie są równoważne. Którychsh
używasz? W jakim systemie operacyjnym? i Który sed (może?sed --version
jeśli to nie zawiedzie)?