Command-Line

命令參數的位置

  • May 9, 2018

我認為任何命令的參數位置都不是固定的。

例如,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

一些 GNU 實用程序會默默地重新組織命令行參數,以便選項和選項參數位於操作數之前。這不是標準行為。

符合標準的實用程序期望選項和選項參數首先出現,當命令行解析器找到第一個非選項參數時,其餘參數被視為操作數:

cp -i file1 file2

在上面,第一個參數是一個選項,而最後兩個參數是操作數。

cp file1 file2 -i

上面有三個操作數,一個非 GNU 實現cp將複製file1file2放入被呼叫的目錄中-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

grep您需要使用 GNU編寫:

grep -- 'PATTERN' *.txt

或者

grep -e 'PATTERN' -- *.txt

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

您的ldd(在 GNU 系統上是一個bash手動解析選項的腳本,而不是使用 GNU getopt_long()API)不會以“GNU 方式”解析其命令行參數,這(恕我直言)它正在正確執行。


來自 GNU 文件getopt_long(3)

預設情況下,在掃描時getopt()對 的內容進行置換argv,以便最終所有非選項都位於末尾。

$$ … $$optstring如果is的第一個字元+或設置了環境變數POSIXLY_CORRECT,則一旦遇到非選項參數,選項處理就會停止。

引用自:https://unix.stackexchange.com/questions/442715