命令参数的位置

命令参数的位置

我认为任何命令的参数位置都是不固定的。

例如,cp -r ./abc ./defcp ./abc ./def -r是相同的,grep -rnH hello .grep hello . -rnH是相同的......

然而,今天当我使用的时候ldd,我发现我错了。因为ldd -r x.soldd x.so -r不一样。第二个命令给了我一个错误:

ldd: ./-r: No such file or directory

为什么我们不能改变参数的位置ldd

答案1

一些 GNU 实用程序会默默地重新组织命令行参数,以便选项和选项参数位于操作数之前。这不是标准行为。

符合标准的实用程序期望选项和选项参数首先出现,当命令行解析器找到第一个非选项参数时,其余参数将被视为操作数:

cp -i file1 file2

在上面,第一个参数是选项,最后两个参数是操作数。

cp file1 file2 -i

上面有三个操作数,非 GNU 实现cp会将file1和复制file2到名为的目录中-i(如果不存在这样的目录,则给出错误消息)。cp另一方面,GNU将其-i视为一个选项,并询问我是否要覆盖file2该文件(如果该文件存在)。

通过设置环境变量可以纠正此行为POSIXLY_CORRECT

$ cp file1 file2 -i
cp: overwrite 'file2'? n

$ POSIXLY_CORRECT=1 cp file1 file2 -i
cp: target '-i' is not a directory

或者你可以--明确地标记选项的结尾(无论命令是否以 GNU 方式解析其选项,这都会起作用):

$ cp -- file1 file2 -i
cp: target '-i' is not a directory

在以下事情中需要记住这一点:

grep 'PATTERN' *.txt

对于 GNUgrep你需要这样写:

grep -- 'PATTERN' *.txt

或者

grep -e 'PATTERN' -- *.txt

如果PATTERN某些.txt文件的名称或名称以-.

您的ldd(在 GNU 系统上是一个bash手动解析选项的脚本,而不是使用 GNU getopt_long()API)不会以“GNU 方式”解析其命令行参数,(恕我直言)它做得正确。


来自 GNU 文档getopt_long(3)

默认情况下,在扫描时getopt()排列 的内容argv,以便最终所有非选项都位于末尾。 [...] 如果设置了optstringis的第一个字符+或环境变量POSIXLY_CORRECT,则一旦遇到非选项参数,选项处理就会停止。

相关内容