Если я запускаю следующий файл .sh:
#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'
Результатом является ошибка:
sed: -e выражение # 1, символ 18: недопустимый конец диапазона
Но если я запускаю следующий файл .sh:
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
Работает без ошибок. Разве второй код не должен быть эквивалентным первому? Почему ошибка в первом?
shell-script
shell
sed
options
Родриго
источник
источник
sh
одинаковы. Не все sed эквивалентны. Чтоsh
вы используете? В какой ОС? и какой сед (возможно?sed --version
если не подведет)?LC_COLLATE=C
(илиPOSIX
) для звонка, чтобыsed
обойти проблемуPOSIXLY_CORRECT=y
в среде, второй не имеетPOSIXLY_CORRECT
в среде. Оболочка, из которой я вызываю оба сценария, отсутствуетPOSIXLY_CORRECT
в ее среде.echo "a" | POSIXLY_CORRECT=y sed -e 's/[\d001-\d008]//g'
воспроизведите вашу проблемуОтветы:
Когда bash вызывается с именем
sh
, он делает это :а затем позже устанавливает
POSIXLY_CORRECT
переменную оболочкиy
:bind_variable
вызовыbind_variable_internal
, которые, если в это время включен атрибут оболочкиa
(что было бы, если бы вы вызвали оболочку-a
), помечают переменную оболочки как экспортированную .Итак, в вашем первом сценарии:
sed
вызываетсяPOSIXLY_CORRECT=y
в его среде, что заставит его жаловаться[\d001-\d008]
. (То же самое происходит, если sed предоставлена--posix
опция.)В ГНУ СЭД, является кодом выхода для символа которого численное значение в базе-10 NNN , но в режиме POSIX, это отключено внутри выражения кронштейна, так что , буквально означает символы , и т.д., при этом диапазон от к . В порядке кодов символов, предшествует (и диапазон включает все цифры, кроме нуля, плюс все заглавные буквы, а также некоторые специальные символы). В используемой вами локали сортирует , однако, поэтому диапазон недопустим.
\dNNN
[\d001-\d008]
\
d
1
\
1
\
en_US.UTF-8
\
1
В вашем втором сценарии:
Несмотря на то, что
POSIXLY_CORRECT
он установлен в оболочке, он не экспортируется, поэтому sed вызывается без использованияPOSIXLY_CORRECT
в среде, а sed запускается с расширениями GNU.Если вы добавите
export POSIXLY_CORRECT
в верхней части вашего второго скрипта, вы также увидите жалобу sed.источник
/bin/sh
самом деле Bash). То же самое происходит, если находится в среде до запуска Bash: он также передает его как .POSIXLY_CORRECT
sh
POSIXLY_CORRECT=y
POSIXLY_CORRECT
не в среде, когда запускается оболочка, и сценарий не устанавливает ее. Оболочка делает. Он создает переменную среды из ниоткуда, что очень плохо, поскольку он делает это в режиме, в котором он должен быть, и пытается соответствовать стандарту.POSIXLY_CORRECT
самостоятельно. Там нет упоминания об этом в списке эффектов режима POSIX, а описание переменной говорит только о том, что установка этого параметра переводит оболочку в режим POSIX, а не наоборот.allexport
.