Bash

替換文件時維護(或恢復)文件權限

  • June 26, 2019

我有一個接受文件作為參數的命令,修改文件,然後將其寫入第二個參數中指定的文件名。我會呼叫那個程序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. 使用新版本創建一個臨時文件,然後將其移動到位。
  • 優點:如果程序打開該文件,它將讀取舊內容或新內容,具體取決於它是在移動之前還是之後打開文件。沒有混淆。
  • 優點:如果發生崩潰,舊的內容會被保留。
  • 缺點:由於創建了一個新文件,因此不會保留文件的屬性(所有權、權限等)。
  1. 覆蓋舊文件。
  • 優點:保留了文件的屬性。
  • 缺點:如果發生崩潰,文件可能會寫一半。
  • 缺點:如果程序在更新時打開了文件,該程序可能會讀取不一致的數據。

如果可以,請使用方法 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"

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