Linux Shell 找出修改過的檔案做 scp 指令(特殊檔名處理)

想要定時同步有新增、修改的檔案,可以使用 rsync 達成。

但是若檔案數太多,用 rsync 光 diff 就會花掉很多時間,這時候可以考慮使用 find 先找出有修改過的檔案,再來做 scp 即可。

註:此篇環境為 Debian / Ubuntu Linux + Bash Shell

Linux Shell 找出修改過的檔案做 scp 指令(特殊檔名處理)

使用 find 找出有新增、修改過的檔案,再來做 scp 是很一般的事情。但是裡面如果遇到特殊檔名,ex: '、"、空格 或 - ...  等等,要怎麼做呢?

前置作業

先製造特殊檔名的清單,以下都使用 touch 就可以完成 (放在 /tmp/test/)

  • 'test.txt
  • 中文.txt
  • {}.txt
  • "test.txt
  • test abc.txt # touch "test abc.txt"
  • -test.txt # touch -- -test.txt

上述的檔名裡面,遇到比較難處理的反而是檔名中間有空白的("test abc.txt"),原因如下:

使用 find ./ -type f 遇到中間有空白的檔案會變成兩個 (test、abc.txt),可以使用此參數解決:

  • IPS=$'\n' # 有空格的的檔案會變成1個

注意:下述測試時,可以將指令的 -ctime -1 拿掉,列出所有檔案,然後將所有檔案 scp 過去,確認正常就沒事了。

以下是將 /tmp/test scp 到 example.com:test/

解法1

IFS=$'\n'
for i in `find ./ -type f -ctime -1`
do
  scp $i example.com:test/
done

解法2 (感謝 toodoo)

  • find ./ -type f -ctime -1 -print0 | xargs -0 -I{} scp {} example.com:test/

解法3

下述執行任何一個都可以解決這些檔名問題:

  • find ./ -type f -ctime -1 | xargs -0 -ILIST scp LIST example.com:test/
  • find ./ -type f -ctime -1 | xargs -0 -I{} scp {} example.com:test/ # 與上面那行做法一樣
  • find ./ -type f -print | awk '{print "scp "$0" example.com:test/"}' | sh
  • 註:會於最後一行出現個錯誤訊息(: No such file or directory),不過不用擔心,都是正常 scp (因為 xargs -0 -I... 最後面會多一行換行)

相關網頁

作者: Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.

在〈Linux Shell 找出修改過的檔案做 scp 指令(特殊檔名處理)〉中有 2 則留言

  1. 其實不需要修改IFS, 直接執行以下指令就可以達到您要的功能:

    find ./ -type f -ctime -1 -print0 | xargs -0 -I{} scp {} example.com:test/

    "-print0"意思是用NULL字元分隔檔名, 搭配xargs -0就不用怕遇到任何特殊字元了.
    給您參考一下.

    1. 可以耶,感謝指點。

      我之前測試過 -print0,但是也都 scp 失敗,應該是我沒有搭配 xargs -I{} 的部份。

      剛剛確認 -print0 就不會出現最後一行是空的錯誤訊息,萬分感謝~

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料