管道查找到 xargs 時,無法修改位於不同位置的同名文件
在 Mac 上使用 gnu 工具
我不確定發生了什麼,但似乎將 find 的輸出通過管道傳輸到 xargs 在觸摸出現在不同位置的目錄結構中的同名文件時存在一些問題
我的目錄:
dir -- dirone ---- myfile.txt ---- otherfile.txt -- dirtwo ---- myfile.txt
當我執行此命令時,出現權限被拒絕錯誤:
find dir -name "myfile.txt" | xargs -0 -I FILE sh -c "ls FILE"
我什至不能觸摸/ls文件。如果我訪問其中有一個的“otherfile.txt”,我看不到任何問題
find dir -name "otherfile.txt" | xargs -0 -I FILE sh -c "ls FILE"
是否有某種競爭條件或什麼?我最終想修改文件,
sed -i
但我什至不能。我不明白,因為完整的文件路徑正在傳遞給 xargs 所以它應該有完整的路徑,這使得它的同名無關緊要嗎?編輯:好的,仍然不明白為什麼我會收到燙髮錯誤,但這似乎有效:
find dir -name "otherfile.txt" -type file -print0 | xargs -0 -I FILE sh -c "ls FILE"
只是刪除
-0
也有效,我不確定哪種方式更好/更安全?
鑑於您的目錄設置:
$ find dir dir dir/dirtwo dir/dirtwo/myfile.txt dir/dirone dir/dirone/myfile.txt dir/dirone/otherfile.txt
如果我使用您的(原始)命令,那麼我可以重現您的原始問題:
$ find dir -name "myfile.txt" | xargs -0 -I FILE sh -c "ls FILE" dir/dirtwo/myfile.txt sh: line 1: dir/dirone/myfile.txt: Permission denied $
為了更好地理解發生了什麼,讓我們嘗試該命令的變體:
$ find dir -name "myfile.txt" | xargs -0 -I FILE echo -FILE- -dir/dirtwo/myfile.txt dir/dirone/myfile.txt -
請注意, FILE 擴展為單個標記:
dir/dirtwo/myfile.txt\ndir/dirone/myfile.txt\n
. 為什麼?因為您告訴xargs
令牌是 NUL 分隔的(使用-0
開關),並且兩個文件名之間沒有 NUL 字元。有了這個,如果我們回到你原來的命令:
... | xargs -0 -I FILE sh -c "ls FILE"
,那變成:ls dir/dirtwo/myfile.txt dir/dirone/myfile.txt
所以它列出了一個,並嘗試執行第二個。這就是你得到“權限被拒絕”的原因——第二個文件不可執行。
如您所見,添加
-print0
選項find
將解決問題。使用該選項,find
將在標記之間放置一個 NUL 字元 -xargs
使用該-0
選項時期望的相同字元。類似地,只需-0
關閉選項即可xargs
解決問題,因為預設情況下兩者都find
使用xargs
空格作為分隔符。
-print0
and選項對於文件名可以包含空格的-0
情況很有用(這會破壞將空格視為標記分隔符的預設行為)。