fed*_*qui 8 bash grep posix gnu environment-variables
Bash中有一个变量POSIXLY_CORRECT
POSIXLY_CORRECT
如果此变量在Bash启动时处于环境中,则shell在读取启动文件之前进入POSIX模式(请参阅Bash POSIX模式),就像提供了--posix调用选项一样.如果在shell运行时设置它,则Bash启用POSIX模式,就像命令一样
Run Code Online (Sandbox Code Playgroud)set -o posix
已被执行.
我被告知有些选项grep
不是POSIX,所以我在The Open Group Base Specifications Issue 6中确认了grep
.所以我检查了GNU grep手册,发现:
grep带有丰富的选项:一些来自POSIX,一些来自GNU扩展.长选项名称始终是GNU扩展名,即使是来自POSIX规范的选项也是如此.POSIX以其短名称指定的选项被明确标记为便于POSIX便携式编程.提供了一些选项名称,以便与较旧或更具异国情调的实现兼容.
它还提到:
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
之前做的所有相同的运行.
从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
默认执行的操作,即在-g
有POSIXLY_CORRECT
和没有的情况下,该标志将被诊断为"无效" .由于eg --ignore-case
是一个有效选项(虽然不是POSIX),因此不会将其诊断为"无效" POSIXLY_CORRECT
.
一般情况下,请查看外部实用程序的文档,了解它们的行为POSIXLY_CORRECT
(如果它们完全关注).本bash
手册只能告诉您该环境变量如何影响shell及其内置命令.