想要定時同步有新增、修改的檔案,可以使用 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... 最後面會多一行換行)
其實不需要修改IFS, 直接執行以下指令就可以達到您要的功能:
find ./ -type f -ctime -1 -print0 | xargs -0 -I{} scp {} example.com:test/
"-print0"意思是用NULL字元分隔檔名, 搭配xargs -0就不用怕遇到任何特殊字元了.
給您參考一下.
可以耶,感謝指點。
我之前測試過 -print0,但是也都 scp 失敗,應該是我沒有搭配 xargs -I{} 的部份。
剛剛確認 -print0 就不會出現最後一行是空的錯誤訊息,萬分感謝~