Use o utilitário install
- é para isso.
Se, durante a execução de um aplicativo, uma das bibliotecas compartilhadas que ele usa for gravada ou truncada, o aplicativo falhará. Mover o arquivo ou removê-lo por atacado com 'rm' não causará uma falha, porque o SO (neste caso, mas eu presumo que isso seja verdade no Linux e em outros * nix também) é inteligente o suficiente para não excluir o inode associado o arquivo enquanto qualquer processo o abrir.
Eu tenho um script de shell que executa a instalação de bibliotecas compartilhadas. Às vezes, ele pode ser usado para reinstalar versões de bibliotecas compartilhadas que já estavam instaladas, sem uma desinstalação primeiro. Como os aplicativos podem estar usando as bibliotecas compartilhadas já instaladas, é importante que o script seja inteligente o suficiente para rm os arquivos ou movê-los para fora do caminho (por exemplo, para uma pasta 'excluída' que o cron poderia esvaziar de cada vez quando não sabemos será executado) antes de instalar os novos, para que não sejam sobrescritos ou truncados.
Infelizmente, recentemente um aplicativo falhou logo após a instalação. Coincidência? É difícil dizer. A solução real aqui é mudar para um método de instalação mais robusto do que um script de shell gigantesco antigo, mas seria bom ter alguma proteção extra até que o switch seja feito. Existe alguma maneira de quebrar um script de shell para protegê-lo de sobrescrever ou truncar arquivos (e, idealmente, falhando alto), mas ainda permitindo que eles sejam movidos ou rm'd?
As permissões de arquivo padrão UNIX não funcionam porque você não pode distinguir mover / remover de sobrescrever / truncar. Os aliases podem funcionar, mas não tenho certeza de quais inteiros de comandos precisam ser aliados. Eu imagino algo como treliça / strace, exceto antes de cada ação que ele verifica contra um filtro se realmente o faz. Não preciso de uma solução perfeita que funcione mesmo contra um script intencionalmente malicioso.
Idéias que tenho até agora:
Use o utilitário install
- é para isso.
Ao instalar um software, especialmente ao instalar um software existente, o modo de operação normal de segurança é (ou eu quero dizer 'deve ser'?):
Se algo der errado enquanto você estiver copiando coisas, você não danificou sua instalação existente. Isso supõe que você tenha espaço livre em disco suficiente, é claro - mas o disco é barato.
Se você estiver escrevendo seus próprios instaladores, poderá fazer algo semelhante a isso. Se você estiver usando instaladores de outras pessoas, você terá dificuldades para lidar com suas peculiaridades. Em última análise, você precisa reclamar com os fornecedores. Mas observe que, se você tentar mexer nos comandos padrão, é provável que as mudanças voltem e mordam você.
Minha primeira inclinação foi sugerir 'set noclobber' em ~ / .bashrc.
Segundo pensamento: o Solaris tem lsof, fuser ou fstat? Estes podem verificar se outro processo tem um arquivo aberto.
Você também pode tentar algo assim:
safecp() {
source=$1
dest=$2
dest_dir=$(dirname dest)
[ -d $dest_dir] || mkdir $dest_dir/temp && mv $dest $dest_dir/temp && cp $source $temp
}
Acho que o rsync pode ser a ferramenta para isso. Você pode querer uma combinação de mudanças de execução ou itemize para atender às suas necessidades exatas. A opção --ignore-existing
também pode ser interessante.
A outra coisa a considerar é que usar o 'cp' entre os limites do sistema de arquivos irá gravar dados no inode atual, enquanto o cp dentro do mesmo sistema de arquivos será desvinculado do arquivo antigo e vinculado ao novo.
Tags installation shell