Rod*_*igo 20 shell sed options shell-script
如果我运行以下 .sh 文件:
#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'
Run Code Online (Sandbox Code Playgroud)
结果报错:
sed: -e 表达式 #1, char 18: 无效范围结束
但是如果我运行以下 .sh 文件:
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
Run Code Online (Sandbox Code Playgroud)
它运行没有错误。第二个代码不应该等同于第一个代码吗?为什么第一个错误?
Mar*_*ick 31
当使用 name 调用 bash 时sh,它会执行以下操作:
if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0')
act_like_sh++;
Run Code Online (Sandbox Code Playgroud)
然后将POSIXLY_CORRECTshell 变量设置为y:
if (act_like_sh)
{
bind_variable ("POSIXLY_CORRECT", "y", 0);
sv_strict_posix ("POSIXLY_CORRECT");
}
Run Code Online (Sandbox Code Playgroud)
bind_variable调用bind_variable_internal,如果当时 shell 属性a处于开启状态(如果您使用 调用 shell 就会如此-a),则将 shell 变量标记为导出的。
所以在你的第一个脚本中:
#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'
Run Code Online (Sandbox Code Playgroud)
sedPOSIXLY_CORRECT=y在其环境中调用 with ,这将使其抱怨[\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'
Run Code Online (Sandbox Code Playgroud)
即使POSIXLY_CORRECT在 shell 中设置,它也不会导出,因此 sed 在没有POSIXLY_CORRECT环境的情况下被调用,并且 sed 使用 GNU 扩展运行。
如果您export POSIXLY_CORRECT在第二个脚本的顶部附近添加,您还会看到 sed 抱怨。