
ファイルを引数として受け入れ、ファイルを変更してから、2番目の引数で指定されたファイル名に書き込むコマンドがあります。私はこのプログラムをと呼ぶmodifyfile
。
私はそれが「所定の位置で」動作したいので、一時ファイルに変更してから再度移動するシェルスクリプト(bash)を作成しました。
TMP=`mktemp`
modifyfile "$original" "$TMP"
mv -v "$TMP" "$original"
残念ながら、これはファイルに対する権限を破壊します。ファイルはデフォルト権限で再生成されます。
mv
権限を変更せずにターゲットを上書きするようにコマンドに指示する方法はありますか?または、元のユーザー、グループ、および権限を保存および復元する方法はありますか?
答え1
使用されず、リダイレクトのみmv
ですcat
。たとえば、
TMP=$(mktemp)
modifyfile "$original" "$TMP"
cat "$TMP" > "$original"
これにより、ファイルレベルで何も触れることなく$original
内容が上書きされます。$TMP
答え2
ファイルを新しいバージョンに置き換えるには2つの戦略があります。
新しいバージョンで一時ファイルを作成し、その場所に移動します。
- 利点:プログラムがファイルを開くと、移動前または後にファイルを開いたかどうかに応じて、古い内容または新しい内容が読み取られます。混乱はありません。
- 利点:競合が発生すると、古いコンテンツが保持されます。
- 欠点:新しいファイルが作成されるため、ファイルのプロパティ(所有権、権限など)は維持されません。
古いファイルを所定の位置に上書きします。
- 利点:ファイルのプロパティを維持します。
- 欠点:競合が発生すると、ファイルが半分しか記録されないことがあります。
- 欠点:ファイルの更新中にプログラムがファイルを開くと、プログラムは一貫性のないデータを読み取ることがあります。
可能であれば、方法1を使用してくださいcp -p --attributes-only
。しかし、まずGNU coreutils(つまり、組み込みのLinuxや十分なLinuxに似た環境)が必要です。cp
1つもない場合は、この--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"
答え3
最初の答えについて議論した後、私は他の答えを思い出しました。
TMP="$(mktemp "$original".XXXXXXXXXX)"
modifyfile "$original" "$TMP"
chmod --reference="$original" "$TMP"
chown --reference="$original" "$TMP"
mv -f "$TMP" "$original"
コメント:
- 一時ファイルは
$original
。mktemp
/tmp
$original
/tmp
mktemp
結果にスペースが含まれている場合は、引用符が付きます。- 「代わりに」を使用する
$()
理由は、それがよりきれいだと思うからです。 ch{mod,own} --reference
$original
に権限を転送するために使用されます$TMP
。どのメタデータを転送でき、転送する必要があるかについて他のアイデアがある人がいる場合は、自分の投稿を編集して追加してください。- ああ、そしてGilesが指摘したように、ルートアクセスが必要です。さて、今書いたので、渡さないでください:P