Quando o bash é chamado com o nome sh
, ele faz isso :
if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == 'if (act_like_sh)
{
bind_variable ("POSIXLY_CORRECT", "y", 0);
sv_strict_posix ("POSIXLY_CORRECT");
}
')
act_like_sh++;
e depois define o shell POSIXLY_CORRECT
variável para y
:
#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'
bind_variable
chamadas bind_variable_internal
, que, se o atributo de shell a
estiver ativado no momento (o que seria se você invocasse o shell com -a
), favor a variável shell como exportada .
Então, no seu primeiro roteiro:
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
sed
é invocado com POSIXLY_CORRECT=y
em seu ambiente, o que fará com que ele se queixe de [\d001-\d008]
. (A mesma coisa acontece se o sed receber a opção --posix
.)
No GNU sed, \dNNN
é um código de escape para o caractere cujo valor numérico na base 10 é NNN , mas no modo POSIX, isso é desativado dentro de uma expressão de colchetes, portanto [\d001-\d008]
, significa literalmente os caracteres \
, d
, etc., com o intervalo sendo de 1
a \
. Na ordem dos códigos de caracteres, 1
vem antes de \
(e o intervalo inclui todos os dígitos, exceto zero, além de todas as letras maiúsculas, além de alguns caracteres especiais). No en_US.UTF-8
locale que você estava usando, \
ordena antes de 1
, mas o intervalo é inválido.
No seu segundo script:
if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == 'if (act_like_sh)
{
bind_variable ("POSIXLY_CORRECT", "y", 0);
sv_strict_posix ("POSIXLY_CORRECT");
}
')
act_like_sh++;
mesmo que POSIXLY_CORRECT
esteja definido no shell, ele não é exportado, portanto, o sed é invocado sem POSIXLY_CORRECT
no ambiente e o sed é executado com as extensões do GNU.
Se você adicionar export POSIXLY_CORRECT
próximo ao topo do seu segundo script, você também verá a reclamação de sed.