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_CORRECTzmienną powłoki nay :
if (act_like_sh)
{
bind_variable ("POSIXLY_CORRECT", "y", 0);
sv_strict_posix ("POSIXLY_CORRECT");
}
bind_variablewywołań bind_variable_internal, które, jeśli atrybut powłoki ajest 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'
sedjest wywoływane POSIXLY_CORRECT=yw jego środowisku, co spowoduje, że narzeka [\d001-\d008]. (To samo dzieje się, jeśli podano --posixopcję 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 \, ditp, przy czym zakres wynosi od 1do \. W kolejności kodów znaków 1wystę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-8ustawieniach 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_CORRECTjest ustawiony w powłoce, nie jest eksportowany, więc sed jest wywoływany bez POSIXLY_CORRECTw ś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.
shsą takie same. Ani wszystkie sed nie są równoważne. Którychshużywasz? W jakim systemie operacyjnym? i Który sed (może?sed --versionjeśli to nie zawiedzie)?