鉴于zsh可以破坏所有给定命令的文件:
>*
Run Code Online (Sandbox Code Playgroud)
我认为设置选项noclobber是个好主意。
>| file如果我想在 bash 和 zsh 中使用默认的 clobber 行为,我总是可以使用。(zsh 也允许替代语法>!file)。
noclobber由于 POSIX 兼容性,我猜测默认情况下未设置,但请确保:
设置有什么缺点noclobber吗?
无论如何noclobber只为交互式外壳设置?
Gil*_*il' 34
noclobber默认情况下没有设置的原因是传统。作为用户界面设计的问题,最好让“创建这个新文件”成为简单的操作,并为更危险的操作“创建新文件或覆盖现有文件”设置额外的障碍。因此,这noclobber是一个好主意(>创建一个新文件,>|可能会覆盖现有文件)并且如果 shell 是在几十年后设计的,那么它很可能是默认设置。
我强烈建议在您的交互式 shell 启动文件(.bashrc或.zshrc)中使用以下内容:
set -o noclobber
alias cp='cp -i'
alias mv='mv -i'
Run Code Online (Sandbox Code Playgroud)
在每种情况下(重定向、复制、移动),目标都是在操作可能具有擦除某些现有数据的副作用时添加额外的障碍,即使擦除现有数据不是操作的主要目标。我没有放在rm -i这个列表中,因为擦除数据是rm.
请注意,noclobber并且-i是安全网。如果他们触发,你做错了什么。因此,不要以它们为借口不检查您正在覆盖的内容!关键是您应该检查输出文件不存在。如果您被告知file exists: foo或overwrite 'foo'?,则表示您犯了错误,您应该感到难过并更加小心。特别是,不要养成说y是否提示覆盖的习惯(可以说,别名应该是alias cp='yes n | cp -i' mv='yes n | mv -i',但按Ctrl+C会使输出看起来更好):如果您确实要覆盖,请取消命令,移动或删除输出文件,然后再次运行该命令。
同样重要的是不要养成触发这些安全的习惯,因为如果你这样做,有一天你会在一台没有你的配置的机器上,你会丢失数据,因为你指望的保护是“在那里。
noclobber只会为交互式 shell 设置,因为.bashrc或.zshrc只能由交互式 shell 读取。当然,您不应该以会影响脚本的方式更改 shell 选项,因为它可能会破坏这些脚本。
noclobber在~/.bashrc(for bash) 或~/.zshrc(或更准确地说$ZDOTDIR/.zshrc, for zsh) 中设置shell 选项将使其在交互式 shell 会话中处于活动状态。
非交互式 shell(脚本)不会读取这些文件。
Shell 选项通常不是从父 Shell 继承的。
这意味着您应该能够在这些文件中设置选项,而无需修改现有脚本中的行为,除非脚本显式地获取这些文件。
我可以看到这样做的唯一缺点是你会反复忘记你已经设置了选项,至少在开始时是这样。后来,与所有这类事情,你会开始习惯性地使用>|,甚至在你实际上可能不想揍文件(就像人有别名的情况下rm,cp并mv与-i选项始终设置,最终开始一直使用-f在命令行上)。
不利的noclobber一面是,如果您习惯了主动,那么有一天您会使用一个不处于活动状态的系统,并且您会轻松地执行一个潜在危险的命令,期望它noclobber能够拯救您……但它不会。然后您将不得不希望有一个足够新的备份来恢复您销毁的数据,因为您认为会首先要求您确认。