Answers:
noclobber
默认情况下未设置的原因是传统。就用户界面设计而言,一个好主意是使“创建此新文件”成为简单的操作,而为更危险的操作(“创建一个新文件或覆盖现有文件”)增加一个障碍。因此,这noclobber
是一个好主意(>
创建一个新文件,>|
可能覆盖现有文件),如果几十年后设计了外壳程序,则可能是默认设置。
我强烈建议您在交互式shell启动文件(.bashrc
或.zshrc
)中使用以下命令:
set -o noclobber
alias cp='cp -i'
alias mv='mv -i'
在每种情况下(重定向,复制,移动),目标是在操作可能具有擦除某些现有数据的副作用的情况下增加额外的障碍,即使擦除现有数据不是该操作的主要目标。我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
将仅为交互式外壳设置,因为.bashrc
或.zshrc
仅由交互式外壳读取。当然,您不应以影响脚本的方式更改外壳选项,因为它可能破坏那些脚本。
rm
有一个-I
我可以使用并建议的选项:“在删除三个以上文件之前,或者在递归删除时,提示一次;比侵入性小-i
,同时仍然可以防止大多数错误”
-i
作为默认的参数对他们来说是一个极好的主意,但它应该适用不同的别名,而不是原始文件(例如我总是把alias copy="cp -i"
和alias move="mv -i"
我的.bashrc)。为什么?由于故障模式。当您使用没有cp / mv别名的计算机或其他用户时,会发生什么?文件可能无意间被覆盖(可能未被检测到!)。带有复制/移动别名的相应故障模式:shell抱怨它无法识别该命令。
-i
参数用于cp和mv,这是极好的选择,但是重用cp和mv名称的建议非常糟糕。真是太糟糕了,我不得不拒绝回答。请更改为使用其他别名,然后我将投票给它。
alias RM='command rm'
,它会告诉zsh使用外部命令rm
而不是别名。这样,您就不必依靠--interactive=never
取代先前的内容-i
。
noclobber
在~/.bashrc
(for bash
)或~/.zshrc
(或更确切地说$ZDOTDIR/.zshrc
,对于zsh
)中设置shell选项将使其在交互式shell会话中处于活动状态。
非交互式外壳(脚本)不读取这些文件。
Shell选项通常不从父Shell继承。
这意味着您应该能够在那些文件中设置选项,而无需修改现有脚本中的行为,除非脚本明确地提供了那些文件。
我可以看到的唯一缺点是,至少在开始时,您将一再忘记设置了该选项。后来,与所有这类事情一样,>|
即使在您实际上可能不想破坏文件的情况下,您也将开始习惯使用(就像使用别名的人rm
,cp
并且始终设置mv
了-i
选项,最终开始总是使用-f
在命令行上)。
bash
,如果$SHELLOPTS
($BASHOPTS
针对shopt
那些)在环境中,则选项将被继承(尽管出于这种原因,您通常不希望这样做)。
不利的noclobber
一面是,如果您习惯了活动,那么有一天您将使用一个不活动的系统,并且会巧妙地执行一个潜在危险的命令,期望noclobber
它会为您节省...而它不会。然后,您必须希望有一个足够近的备份来恢复您破坏的数据,因为您假设首先会要求您进行确认。
rm *
……