为什么“#!/ bin / sh -a”中的-a影响sed而“ set -a”却不影响?


20

如果我运行以下.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'

它运行没有错误。第二个代码不是应该等同于第一个吗?为什么在第一个错误?


并非都sh一样。也不是所有sed都是等效的。sh您正在使用哪个?在哪个操作系统上?和哪个sed(也许?sed --version如果没有失败)?
以撒

1
设置LC_COLLATE=C(或POSIX)以sed解决该问题的电话
Jeff Schaller

4
我发现一个差异:第一个脚本POSIXLY_CORRECT=y在环境中调用sed(可能是其他实用程序),第二个脚本在环境中没有调用POSIXLY_CORRECT。我从中调用这两个脚本的外壳POSIXLY_CORRECT在其环境中没有。
Mark Plotnick

1
嗯,echo "a" | POSIXLY_CORRECT=y sed -e 's/[\d001-\d008]//g' 重现您的问题
Isaac

1
确认上述操作完全不符合CentOS 7.x上显示的OP的要求-GNU bash,版本4.2.46(2)-发行版(x86_64-redhat-linux-gnu)和CentOS Linux版本7.5.1804(核心) 。
slm

Answers:


31

当使用名称调用bash时sh,它将执行以下操作

if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
    act_like_sh++;

然后POSIXLY_CORRECTshell变量设置为y

if (act_like_sh)
  {
    bind_variable ("POSIXLY_CORRECT", "y", 0);
    sv_strict_posix ("POSIXLY_CORRECT");
  }

bind_variable电话bind_variable_internal,其中,如果shell属性a是在时间(如果你调用与外壳这将是-a),标记为shell变量输出

因此,在您的第一个脚本中:

#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'

sedPOSIXLY_CORRECT=y在其环境中被调用,这会使它抱怨[\d001-\d008]。(如果给sed --posix选项,也会发生同样的事情。)

在GNU sed中,是用于在其数值的字符的转义码碱-10是NNN,但在POSIX模式,这是一个括号表达式中被禁止,因此,装置字面上字符,等,具有范围从被到。按字符代码的顺序,先于\dNNN[\d001-\d008]\d1\1\(并且范围包括除零以外的所有数字,所有大写字母以及一些特殊字符)。在en_US.UTF-8您使用的语言环境中,\在之前排序1,因此范围无效。

在第二个脚本中:

#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'

即使POSIXLY_CORRECT是在外壳中设置的,它也不会导出,因此sed会POSIXLY_CORRECT在没有环境的情况下被调用,并且sed使用GNU扩展运行。

如果export POSIXLY_CORRECT在第二个脚本的顶部附近添加,则还会看到sed抱怨。


6
对我来说,这是一个错误。
斯特凡Chazelas

1
圣壳恐怖,蝙蝠侠!这是一个有趣的怪癖(和有点变化的看到,来自于一个问题/bin/sh实际上击)。如果POSIXLY_CORRECTshBash启动之前的环境中,也会发生同样的情况:它也会以方式传递给Bash POSIXLY_CORRECT=y
ilkkachu

3
@StevenPenny,但是在外壳程序启动时POSIXLY_CORRECT 不在环境中,并且脚本未设置它。外壳可以。它无处不在地创建了一个环境变量,这是非常糟糕的,因为它以一种应有的方式进行操作,并试图符合标准。
ilkkachu

4
FWIW,Bash似乎也没有证明它会POSIXLY_CORRECT自行设置。在POSIX模式的效果列表中没有提及它,而变量描述仅表示设置它会将Shell更改为POSIX模式,而不是相反。
ilkkachu

1
@ilkkachu。做完了 我认为POSIX规范也应进行更新,以阐明哪些变量受的影响allexport
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.