У меня есть команда, которая принимает файл в качестве аргумента, изменяет файл, а затем записывает его в имя файла, указанное во втором аргументе. Я позвоню этой программе modifyfile
.
Я хотел, чтобы он работал «на месте», поэтому я написал сценарий оболочки (bash), который изменяет его во временный файл, а затем перемещает обратно:
TMP=`mktemp`
modifyfile "$original" "$TMP"
mv -v "$TMP" "$original"
У этого есть неприятный побочный эффект разрушения разрешений на этот файл. Файл воссоздается с разрешениями по умолчанию.
Есть ли способ сказать mv
команде перезаписать место назначения без изменения его разрешений? Или, альтернативно, есть способ сохранить пользователя, группу и разрешения из оригинала и восстановить их?
источник
rm "$TMP"
, но, похоже, я делаю то, что хочу.mv
вместо этого. Я не вижу способа решить эту проблему.chown
работает только как root.chmod
иchgrp
может или не может работать в зависимости от разрешений пользователя. Ни один из них не копирует другие атрибуты, такие как ACL или расширенные атрибуты файловой системы.Существует две стратегии замены файла новой версией:
Создайте временный файл с новой версией, затем переместите его на место.
Перезаписать старый файл на месте.
Если вы можете, используйте метод 1, но сначала скопируйте атрибуты исходного файла с
cp -p --attributes-only
. Для этого требуется GNU coreutils (то есть не встроенный Linux или достаточно Linux-подобные среды). Если у васcp
его нет--attributes-only
, пропустите этот параметр: он будет работать, но он также будет реплицировать данные.Если вы не можете реплицировать атрибуты существующего файла, например, из-за того, что у вас есть права на запись в него, но вы не владеете им и хотите сохранить владельца, тогда возможен только метод 2. Чтобы минимизировать риск потери данных:
источник
cp -p --attributes-only "$original" "$tmp"
не будут использовать ресурсы для копирования содержимого файла. Я не мог найти, с какой версии этот аргумент был добавлен.cp
реализациями такого ещё нет .После нашего обсуждения первого ответа я предлагаю другой ответ:
Примечания:
$original
вmktemp
шаблоне, чтобы убедиться, что временный файл находится не в,/tmp
а в той же папке, что и$original
. Я считаю, что если/tmp
смонтирована на другой файловой системе, операция больше не будет атомарной.mktemp
теперь указывается в случае, если он содержит пробелы.$()
вместо ``, потому что я считаю это чище.ch{mod,own} --reference
используются для передачи разрешений$original
на$TMP
. Если у кого-то есть дополнительные идеи, какие метаданные можно и нужно передавать, отредактируйте мой пост и добавьте его.источник