Bash
使用帶變數的 rm 命令的危險
我正在創建一個 crontab,它將我的安全攝像頭中的 15 分鐘剪輯壓縮成一個文件(24 小時長),然後刪除這些剪輯。
avimerge -o /media/jmartin/Cams/video/Full_$(date +%F --date "Yesterday") -i /media/jmartin/Cams/video/$(date +%F --date "Yesterday")* # Converts files from the past 24 hours into one .avi rm /media/jmartin/Cams/video/$(date +%F --date "Yesterday")* # Removes old clips that have already been compressed
我的問題是使用 $date 變數有什麼危險。它會在刪除 /video/ 中的所有文件的情況下發生什麼事情嗎?您會推薦什麼作為更安全的選擇?
範例文件名(是的,這些是文件名中的空格):
2016-04-25 00:00:01.avi 2016-04-25 00:15:02.avi 2016-04-25 00:30:02.avi 2016-04-25 00:45:01.avi
有兩件事跳出來:
- 您沒有檢查替換失敗
- 如果日期在
date
命令的使用之間發生變化,則存在競爭條件。你可以像這樣解決它們:
#/bin/bash # Exit if any command fails set -e dir='/media/jmartin/Cams/video' day=$(date +%F --date Yesterday) # Conbine files from the past 24 hours into a single AVI file avimerge -o "$dir/Full_$day" -i "$dir/$day"* # Remove old clips that have already been compressed rm "$dir/$day"*
從
$(date +%F --date "Yesterday")
技術上講,它不是變數,而是命令替換,但這與您的問題無關。如果由於某種原因該date
命令不在您$PATH
的/video/
. 如果您改為使用該命令替換並將其分配給命令之前的變數,然後在and命令avimerge
中使用該變數,您不僅可以確保正在操作的日期字元串不會更改,而且您還能夠在任一命令之前測試零長度變數,並且(如果您有零長度字元串)在執行您不想執行的操作之前退出。avimerge``rm