Jeśli uruchomię następujący plik .sh:
#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'
Rezultatem jest błąd:
sed: -e wyrażenie # 1, char 18: Niepoprawny koniec zakresu
Ale jeśli uruchomię następujący plik .sh:
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
Działa bez błędów. Czy drugi kod nie powinien być równoważny z pierwszym? Dlaczego błąd w pierwszym?
shell-script
shell
sed
options
Rodrigo
źródło
źródło
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)?LC_COLLATE=C
(lubPOSIX
) połączenia w celused
obejścia problemuPOSIXLY_CORRECT=y
w środowisku, a drugi nie ma goPOSIXLY_CORRECT
w środowisku. Powłoka, z której wywołuję oba skrypty, nie maPOSIXLY_CORRECT
w swoim środowisku.echo "a" | POSIXLY_CORRECT=y sed -e 's/[\d001-\d008]//g'
odtwórz swój problemOdpowiedzi:
Kiedy bash jest wywoływany z nazwą
sh
, robi to :a następnie ustawia
POSIXLY_CORRECT
zmienną powłoki nay
:bind_variable
wywołańbind_variable_internal
, które, jeśli atrybut powłokia
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:
sed
jest wywoływanePOSIXLY_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 od1
do\
. W kolejności kodów znaków1
występuje przed\
(a zakres obejmuje wszystkie cyfry oprócz zera, plus wszystkie duże litery oraz niektóre znaki specjalne). Jednak wen_US.UTF-8
ustawieniach regionalnych, których używasz,\
sortuje się wcześniej1
, więc zakres jest nieprawidłowy.W twoim drugim skrypcie:
nawet jeśli
POSIXLY_CORRECT
jest ustawiony w powłoce, nie jest eksportowany, więc sed jest wywoływany bezPOSIXLY_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.źródło
/bin/sh
faktycznie jest bash). To samo dzieje się, jeśliPOSIXLY_CORRECT
jest w środowisku przed rozpoczęciemsh
Bash: przekaże go również jakoPOSIXLY_CORRECT=y
.POSIXLY_CORRECT
nie ma go w środowisku, gdy uruchamia się powłoka, a skrypt go nie ustawia. Powłoka działa. Tworzy zmienną środowiskową znikąd, co jest szczególnie złe, ponieważ robi to w trybie, w którym powinna być, i stara się być zgodna ze standardami.POSIXLY_CORRECT
. Nie ma o tym wzmianki na liście efektów trybu POSIX, a opis zmiennej mówi tylko, że ustawienie go zmienia powłokę w tryb POSIX, a nie na odwrót.allexport
.