Linux

使用 xargs 複製目錄

  • January 5, 2021

我正在嘗試編寫一個腳本來將今天創建的一組目錄複製到另一個目錄。

我目前正在使用:

find /test/downloads/ -mindepth 1 -maxdepth 1 -type d -mtime -1 -printf '%f\n' | xargs -I '{}' cp -R '{}' /test/uploads/

但這給了我一個錯誤:

cp: cannot stat 'foo': No such file or directory

我錯過了什麼?

-printf '%f\n'是一個 GNU 擴展,它列印目前文件路徑的尾隨部分,後跟換行符。如果文件路徑是/test/downloads/foo,則列印foo\n.

xargs接受那個輸出。這裡foo不包含用xargswith特殊處理的字元-I{}(引號字元、換行符(唯一的分隔符用-I)和前導空格、帶有一些的 EOF 字元)。

所以在傳遞給的參數中{}被替換為. 所以最終被, , ,作為參數呼叫。foo``cp``cp``cp``-R``foo``/test/uploads/

所以cpfoo在目前工作目錄中查找,而不是在/test/downloads.

如果該文件已被呼叫/test/downloads/-t..,則該命令將是

cp -R -t.. /test/uploads/

它告訴cp複製/test/uploads/到目前工作目錄的父目錄。

如果文件名是/test/downloads/ 'blah'<newline>"blah",cp會被呼叫兩次cp -R blah /test/uploads/.

所以你有兩個問題:

  1. 使用%f,您將前導目錄組件剝離到文件中
  2. 您正在使用xargswhich 不能可靠地用於(處理 NUL 分隔記錄find的非標準-r和選項除外)的輸出。-0

還可以添加您正在呼叫cp每個目錄,即使cp它能夠一次複製多個文件。

在這裡,標準情況下,應該是:

find /test/downloads/. ! -name . -prune -type d -mtime -1 -exec sh -c '
 exec cp -R "$@" /test/uploads/' sh {} +

使用這些實用程序的 GNU 實現(預設在您的 Debian 系統中找到)可以簡化為:

find /test/downloads/ -mindepth 1 -maxdepth 1 -type d -mtime -1 \
 -exec cp -Rt /test/uploads/ {} +

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