Existem desvantagens em configurar o `noclobber`?

19

Dado que zshpode derrotar todos os arquivos, dado o comando:

>*

Eu estou pensando que definir a opção noclobberseria uma boa idéia.

Eu sempre posso usar >| filese eu quiser usar o comportamento padrão do clobber no bash e no zsh. (zsh também permite a sintaxe alternativa >!file).

Acho que noclobbernão está definido por padrão por causa da compatibilidade com POSIX, mas apenas para ter certeza:

Existem desvantagens na configuração noclobber?

Existe uma maneira de definir noclobberapenas para o shell interativo?

Tom Hale
fonte
3
Estou zsh surpreso não, pelo menos avisar sobre isso, já que ele não avisar sobre algo como rm *...
ilkkachu

Respostas:

23

O motivo noclobbernão é definido por padrão é tradição. Por uma questão de design da interface do usuário, é uma boa idéia tornar "criar este novo arquivo" a ação fácil e colocar um obstáculo extra na ação mais perigosa "criar um novo arquivo ou substituir um arquivo existente". Portanto, noclobberé uma boa idéia ( >criar um novo arquivo, >|potencialmente substituir um arquivo existente) e provavelmente teria sido o padrão se o shell tivesse sido projetado algumas décadas depois.

Eu recomendo usar o seguinte no arquivo de inicialização do shell interativo ( .bashrcou .zshrc):

set -o noclobber
alias cp='cp -i'
alias mv='mv -i'

Em cada caso (redirecionamento, cópia, movimentação), o objetivo é adicionar um obstáculo extra quando a operação tiver o efeito colateral de apagar alguns dados existentes, mesmo que a exclusão de dados existentes não seja o objetivo principal da operação. Eu não coloquei rm -inesta lista porque apagar os dados é o objetivo principal rm.

Observe noclobbere -isão redes de segurança . Se eles dispararem, você fez algo errado . Portanto, não use-os como desculpa para não verificar o que você está substituindo! O ponto é que você deveria ter verificado se o arquivo de saída não existe. Se você for informado file exists: fooou overwrite 'foo'?, significa que cometeu um erro e deve se sentir mal e ter mais cuidado. Em particular, não adquira o hábito de dizer yse for solicitado a substituir (sem dúvida, os aliases devem ser alias cp='yes n | cp -i' mv='yes n | mv -i', mas pressionar Ctrl+ Cfaz com que a saída pareça melhor): se você quis substituir, cancele o comando, mova ou remova a saída arquivo e execute o comando novamente.

Também é importante não adquirir o hábito de acionar essas seguranças, porque se o fizer, um dia você estará em uma máquina que não possui sua configuração e perderá dados porque as proteções que contava não são ' t lá.

noclobberserá definido apenas para shells interativos, pois .bashrcou .zshrcé lido apenas por shells interativos. É claro que você não deve alterar as opções do shell de maneira a afetar os scripts, pois isso pode ser interrompido.

Gilles 'SO- parar de ser mau'
fonte
6
rmtem uma opção -Ique eu uso e recomendo: "avise uma vez antes de remover mais de três arquivos ou remova recursivamente; menos invasivo que -i, ao mesmo tempo em que protege contra a maioria dos erros"
Reid
8
Eu recomendo fortemente não alterar o nome do cp e mv dessa maneira. No entanto, usar -icomo argumento padrão para eles é uma excelente idéia, mas deve ser aplicada em diferentes nomes alternativos , não nos originais (por exemplo, eu sempre coloco alias copy="cp -i"e alias move="mv -i"no meu .bashrc). Por quê? Por causa do modo de falha. O que acontece quando você usa uma máquina ou um usuário diferente que não possui os aliases cp / mv? Arquivos potencialmente substituídos sem intenção (possivelmente não detectados!). Modo de falha correspondente com alias de copiar / mover: o shell reclama que não reconhece o comando.
Hjdaldal 01/07/19
1
Também existe um modo de falha adicional para o alias cp / mv: ao escrever um script de shell, alguém que é usado para alias cp = "cp -i" pode escrever um comando cp incorretamente, esperando que ele se comporte como em um modo interativo, porque não há diferença de nome. Por outro lado, toda vez que escrevo "copy somefile / some / where" eu sei que uso um alias e não o comando cp diretamente. E mesmo que eu devesse colocar uma cópia em um arquivo shell, ela falharia da mesma maneira que no shell com alias ausente.
Hjdaldal 01/07/19
1
Portanto, TL; DR, o conselho padrão para usar o -iargumento para cp e mv é excelente, mas o conselho para reutilizar os nomes cp e mv é horrivelmente ruim. É tão ruim que tenho que dar uma resposta negativa à resposta. Altere para usar diferentes nomes alternativos e eu votarei em votação positiva.
Hjdaldal 01/07/19
1
@ TomHale Você poderia usar alias RM='command rm', o que diria ao zsh para usar o comando externo em rmvez do alias. Dessa forma, você não precisa confiar em --interactive=neversubstituir uma anterior -i.
Adaephon
6

Definir a noclobberopção do shell em ~/.bashrc(para bash) ou ~/.zshrc(ou mais precisamente $ZDOTDIR/.zshrc, para zsh) o tornará ativo em sessões de shell interativas.

Os shells (scripts) não interativos não leem esses arquivos.

As opções de shell normalmente não são herdadas dos shells pai.

Isso significa que você deve poder definir a opção nesses arquivos sem modificar o comportamento nos scripts existentes, a menos que os scripts os originem explicitamente.

A única desvantagem de fazer isso que posso ver é que você esquecerá repetidamente que definiu a opção, pelo menos no começo. Posteriormente, como em todo esse tipo de coisa, você começará a usar habitualmente >|, mesmo nos casos em que talvez não queira obstruir o arquivo (assim como as pessoas com pseudônimos para rm, cpe mvcom a -iopção sempre definida, eventualmente começará a usar sempre -fna linha de comando).

Kusalananda
fonte
2
Com bash, as opções são herdadas se $SHELLOPTS( $BASHOPTSpara shoptas) estiver no ambiente (algo que você geralmente não gostaria de fazer por esse motivo).
Stéphane Chazelas
3

A desvantagem é que, se você se acostumar a ter noclobberativo, um dia usará um sistema em que ele não está ativo e executará alegremente um comando potencialmente perigoso, esperando noclobberque você o salve ... e isso não acontecerá. E então você terá que esperar que haja um backup recente o suficiente para recuperar os dados que você destruiu, porque você supôs que seria solicitada a confirmação primeiro.

Dave Sherohman
fonte
Claro, um dia você usará um sistema em que ele não está ativo. Ao usar um sistema desconhecido, você deve ter um cuidado especial e garantir que os backups estejam atualizados antes de fazer algo potencialmente destrutivo, como redirecionar a saída para um arquivo.
Gilles 'SO- stop be evil'