When bash is called with the name sh
, it does this:
if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
act_like_sh++;
and then later sets the POSIXLY_CORRECT
shell variable to y
:
if (act_like_sh)
{
bind_variable ("POSIXLY_CORRECT", "y", 0);
sv_strict_posix ("POSIXLY_CORRECT");
}
bind_variable
calls bind_variable_internal
, which, if the shell attribute a
is on at the time (which it would be if you invoked the shell with -a
), marks the shell variable as exported.
So in your first script:
#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'
sed
is invoked with POSIXLY_CORRECT=y
in its environment, which will make it complain about [\d001-\d008]
. (Same thing happens if sed is given the --posix
option.)
In GNU sed, \dNNN
is an escape code for the character whose numerical value in base-10 is NNN, but in POSIX mode, this is disabled inside a bracket expression, so [\d001-\d008]
, means literally the characters \
, d
, etc., with the range being from 1
to \
. In order of character codes, 1
comes before \
(and the range includes all digits except zero, plus all uppercase letters, plus some special characters). In the en_US.UTF-8
locale which you were using, \
sorts before 1
, however, so the range is invalid.
In your second script:
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
even though POSIXLY_CORRECT
is set in the shell, it isn't exported, so sed is invoked without POSIXLY_CORRECT
in the environment, and sed runs with GNU extensions.
If you add export POSIXLY_CORRECT
near the top of your second script, you'll also see sed complain.
sh
are the same. Nor all sed are equivalent. Whichsh
are you using? In which OS? and Which sed (maybe?sed --version
if it doesn't fail)? – Isaac Aug 13 '18 at 16:11LC_COLLATE=C
(orPOSIX
) for the call tosed
works around the issue – Jeff Schaller♦ Aug 13 '18 at 16:13POSIXLY_CORRECT=y
in the environment, the second does not havePOSIXLY_CORRECT
in the environment. The shell I invoke both scripts from does not havePOSIXLY_CORRECT
in its environment. – Mark Plotnick Aug 13 '18 at 18:11echo "a" | POSIXLY_CORRECT=y sed -e 's/[\d001-\d008]//g'
reproduce your problem – Isaac Aug 13 '18 at 18:20