Bash
替換文件時維護(或恢復)文件權限
我有一個接受文件作為參數的命令,修改文件,然後將其寫入第二個參數中指定的文件名。我會呼叫那個程序
modifyfile
。我希望它“就地”工作,所以我編寫了一個 shell 腳本(bash),將其修改為一個臨時文件,然後將其移回:
TMP=`mktemp` modifyfile "$original" "$TMP" mv -v "$TMP" "$original"
這具有破壞該文件的權限的不幸副作用。該文件使用預設權限重新創建。
有沒有辦法告訴
mv
命令在不改變其權限的情況下覆蓋目標?或者有沒有辦法從原始文件中保存使用者、組和權限並恢復它們?
而不是使用
mv
,只是重定向cat
。例如:TMP=$(mktemp) modifyfile "$original" "$TMP" cat "$TMP" > "$original"
這將覆蓋
$original
的內容$TMP
,而不涉及文件級別的任何內容。
用新版本替換文件有兩種策略:
- 使用新版本創建一個臨時文件,然後將其移動到位。
- 優點:如果程序打開該文件,它將讀取舊內容或新內容,具體取決於它是在移動之前還是之後打開文件。沒有混淆。
- 優點:如果發生崩潰,舊的內容會被保留。
- 缺點:由於創建了一個新文件,因此不會保留文件的屬性(所有權、權限等)。
- 覆蓋舊文件。
- 優點:保留了文件的屬性。
- 缺點:如果發生崩潰,文件可能會寫一半。
- 缺點:如果程序在更新時打開了文件,該程序可能會讀取不一致的數據。
如果可以,請使用方法 1,但首先使用 . 複製原始文件的屬性
cp -p --attributes-only
。這需要 GNU coreutils(即非嵌入式 Linux,或足夠類似 Linux 的環境)。如果您cp
沒有--attributes-only
,請忽略此選項:它會起作用,但它也會複製數據。tmp=$(mktemp) cp -p --attributes-only "$original" "$tmp" modifyfile "$original" "$tmp" mv -f "$tmp" "$original"
如果您無法複製現有文件的屬性,例如因為您對它有寫權限但不擁有它並且您想保留所有者,那麼只有方法 2 是可能的。為了最大限度地降低數據失去的風險:
- 使文件不完整的視窗盡可能小。首先在臨時文件中準備數據,然後將其複製到位。
- 首先備份舊文件。
tmp=$(mktemp) backup="${original}~" modifyfile "$original" "$tmp" cp -p "$original" "$backup" cp -f "$tmp" "$original"