Bash

使用帶變數的 rm 命令的危險

  • April 25, 2016

我正在創建一個 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  

有兩件事跳出來:

  1. 您沒有檢查替換失敗
  2. 如果日期在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

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