Если во время работы приложения одна из используемых совместно используемых библиотек будет записана или усечена, приложение выйдет из строя. Перемещение файла или его массовое удаление с помощью 'rm' не вызовет сбоя, потому что ОС (в данном случае Solaris, но я предполагаю, что это верно и для Linux, и для других * nix) достаточно умен, чтобы не удалять индексный дескриптор, связанный с файл, пока он открыт любым процессом.
У меня есть сценарий оболочки, который выполняет установку общих библиотек. Иногда его можно использовать для переустановки уже установленных версий разделяемых библиотек без предварительного удаления. Поскольку приложения могут использовать уже установленные общие библиотеки, важно, чтобы сценарий был достаточно умен, чтобы rm файлы или переместить их в сторону (например, в 'удаленную' папку, которую cron может очистить в то время, когда мы не знаем приложений будут запущены) перед установкой новых, чтобы они не были перезаписаны или усечены.
К сожалению, недавно приложение вылетало сразу после установки. Стечение обстоятельств? Сложно сказать. Реальное решение здесь - переключиться на более надежный метод установки, чем старый гигантский сценарий оболочки, но было бы неплохо иметь дополнительную защиту, пока переключение не будет выполнено. Есть ли способ обернуть сценарий оболочки, чтобы защитить его от перезаписи или усечения файлов (и, в идеале, громкого сбоя), но все же позволяя их перемещать или rm'd?
Стандартные права доступа к файлам UNIX не помогут, потому что вы не сможете отличить перемещение / удаление от перезаписи / усечения. Псевдонимы могут работать, но я не уверен, какую совокупность команд нужно использовать. Я представляю что-то вроде truss / strace, за исключением того, что перед каждым действием он проверяет с помощью фильтра, действительно ли это делать. Мне не нужно идеальное решение, которое работало бы даже против умышленно вредоносного скрипта.
У меня пока есть идеи:
Использовать install
Утилита - вот для чего.
При установке программного обеспечения, особенно при установке поверх существующего программного обеспечения, нормальный безопасный режим работы (или я имею в виду «должен быть»?):
Если что-то пойдет не так во время копирования, значит, вы не повредили существующую установку. Это, конечно, предполагает, что у вас достаточно свободного дискового пространства, но диск стоит дешево.
Если вы пишете свои собственные установщики, вы можете сделать что-то подобное. Если вы используете инсталляторы других людей, вам будет сложно справиться с их причудами. В конечном итоге вам нужно пожаловаться поставщикам. Но учтите, что если вы попытаетесь возиться со стандартными командами, изменения, скорее всего, вернутся и укусят вас.
Моей первой мыслью было предложить «установить noclobber» в ~ / .bashrc.
Вторая мысль: есть ли в Solaris lsof, fuser или fstat? Они могут проверить, есть ли открытый файл у другого процесса.
Вы также можете попробовать что-то вроде этого:
safecp() {
source=$1
dest=$2
dest_dir=$(dirname dest)
[ -d $dest_dir] || mkdir $dest_dir/temp && mv $dest $dest_dir/temp && cp $source $temp
}
Я думаю, что rsync может быть для этого инструментом. Вам может потребоваться комбинация пробного прогона или внесения изменений в детали, чтобы точно соответствовать вашим требованиям. В --ignore-existing
переключатель также может быть интересен.
Другая вещь, которую следует принять во внимание, заключается в том, что использование cp через границы файловой системы будет записывать данные в текущий индексный дескриптор, тогда как cp в той же файловой системе будет отключаться от старого файла и связываться с новым.