命令參數的位置
我認為任何命令的參數位置都不是固定的。
例如,
cp -r ./abc ./def
和cp ./abc ./def -r
是相同的,grep -rnH hello .
並且grep hello . -rnH
是相同的……但是,今天我在使用的時候
ldd
,發現我錯了。因為ldd -r x.so
和ldd x.so -r
不一樣。第二個命令給了我一個錯誤:ldd: ./-r: No such file or directory
為什麼我們不能改變參數的位置
ldd
?
一些 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
grep
您需要使用 GNU編寫:grep -- 'PATTERN' *.txt
或者
grep -e 'PATTERN' -- *.txt
如果
PATTERN
某些.txt
文件的 或名稱以-
.您的
ldd
(在 GNU 系統上是一個bash
手動解析選項的腳本,而不是使用 GNUgetopt_long()
API)不會以“GNU 方式”解析其命令行參數,這(恕我直言)它正在正確執行。來自 GNU 文件
getopt_long(3)
:預設情況下,在掃描時
getopt()
對 的內容進行置換argv
,以便最終所有非選項都位於末尾。$$ … $$
optstring
如果is的第一個字元+
或設置了環境變數POSIXLY_CORRECT
,則一旦遇到非選項參數,選項處理就會停止。