如何在grep中使用POSIXLY_CORRECT?

fed*_*qui 8 bash grep posix gnu environment-variables

Bash中有一个变量POSIXLY_CORRECT

POSIXLY_CORRECT

如果此变量在Bash启动时处于环境中,则shell在读取启动文件之前进入POSIX模式(请参阅Bash POSIX模式),就像提供了--posix调用选项一样.如果在shell运行时设置它,则Bash启用POSIX模式,就像命令一样

set -o posix
Run Code Online (Sandbox Code Playgroud)

已被执行.

我被告知有些选项grep不是POSIX,所以我在The Open Group Base Specifications Issue 6中确认了grep.所以我检查了GNU grep手册,发现:

grep带有丰富的选项:一些来自POSIX,一些来自GNU扩展.长选项名称始终是GNU扩展名,即使是来自POSIX规范的选项也是如此.POSIX以其短名称指定的选项被明确标记为便于POSIX便携式编程.提供了一些选项名称,以便与较旧或更具异国情调的实现兼容.

它还提到:

2.2环境变量

grep的行为受以下环境变量的影响.

POSIXLY_CORRECT
如果设置,grep的行为与POSIX要求相同; 否则,grep的行为更像其他GNU程序.POSIX要求必须将文件名后面的选项视为文件名; 默认情况下,此类选项被置换到操作数列表的前面,并被视为选项.此外,POSIXLY_CORRECT禁用无效括号表达式的特殊处理.请参见invalid-bracket-expr.

使用部分Long选项名称始终是GNU扩展,即使对于来自POSIX规范的选项我说:让我们尝试变量POSIXLY_CORRECT.

所以我尝试了一些不是POSIX的东西:

$ echo "HELLO" | grep --ignore-case 'hello'
HELLO
Run Code Online (Sandbox Code Playgroud)

但令我惊讶的是它也可以设置它:

$ echo "HELLO" | POSIXLY_CORRECT=1 grep --ignore-case 'hello'
HELLO
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?设置POSIXLY_CORRECT grep不能识别长选项名称吗?

如果使用-C不是POSIX 的选项(例如),则会发生相同的情况:

$ POSIXLY_CORRECT=1 grep -C 2 '2' <<< "1
2
3"
1
2
3
Run Code Online (Sandbox Code Playgroud)

以及set -o posix之前做的所有相同的运行.

Kus*_*nda 7

从GNU grep手册:

POSIXLY_CORRECT

如果设置,则grep 表现为POSIX要求; 否则, grep 表现得更像其他GNU程序.POSIX要求必须将文件名后面的选项视为文件名; 默认情况下,此类选项被置换到操作数列表的前面,并被视为选项.此外,POSIX要求将未识别的选项诊断为"非法",但由于它们并非真正违法,因此默认情况下将其诊断为"无效". POSIXLY_CORRECT也禁用 _N_GNU_nonoption_argv_flags_,如下所述.

这意味着POSIXLY_CORRECT环境中为GNU 设置的唯一内容grep是不允许重新排列文件名后面的选项,以便将它们放在前面.它不会使它不采用非POSIX命令行标志.

所以让我们试试:

$ ggrep "hello" myfile -v

$ env POSIXLY_CORRECT=1 ggrep "hello" myfile -v
ggrep: -v: No such file or directory
Run Code Online (Sandbox Code Playgroud)

(在我的BSD系统上grep调用GNU ggrep)

关于手册中"无法识别的选项"的部分是GNU grep默认执行的操作,即在-gPOSIXLY_CORRECT和没有的情况下,该标志将被诊断为"无效" .由于eg --ignore-case是一个有效选项(虽然不是POSIX),因此不会将其诊断为"无效" POSIXLY_CORRECT.

一般情况下,请查看外部实用程序的文档,了解它们的行为POSIXLY_CORRECT(如果它们完全关注).本bash手册只能告诉您该环境变量如何影响shell及其内置命令.

  • 你以微弱优势击败了我.也许强调Bash的文档仅适用于Bash,并且`POSIXLY_CORRECT`设置为`grep`设置的确是`grep`手册所说的. (2认同)