设置“ noclobber”有什么缺点吗?


20

鉴于zsh此命令可以破坏所有文件:

>*

我认为设置该选项noclobber将是一个好主意。

>| file如果我想同时在bash和zsh中使用默认的clobber行为,则可以始终使用。(zsh还允许使用其他语法>!file)。

我猜测noclobber由于POSIX兼容性,默认情况下未设置,但请确保:

设置是否有缺点noclobber

无论如何,是否noclobber只为交互式外壳设置?


3
我很惊讶zsh至少没有警告过,因为它确实警告过类似的东西rm *……
ilkkachu

Answers:


24

noclobber默认情况下未设置的原因是传统。就用户界面设计而言,一个好主意是使“创建此新文件”成为简单的操作,而为更危险的操作(“创建一个新文件或覆盖现有文件”)增加一个障碍。因此,这noclobber是一个好主意(>创建一个新文件,>|可能覆盖现有文件),如果几十年后设计了外壳程序,则可能是默认设置。

我强烈建议您在交互式shell启动文件(.bashrc.zshrc)中使用以下命令:

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

在每种情况下(重定向,复制,移动),目标是在操作可能具有擦除某些现有数据的副作用的情况下增加额外的障碍,即使擦除现有数据不是该操作的主要目标。我rm -i之所以未列入此列表,是因为擦除数据是的主要目标rm

难道注意,noclobber并且-i安全网。如果它们触发了,则说明您做错了什么。因此,不要以它们为借口不检查您要覆盖的内容!关键是您应该检查输出文件不存在。如果您被告知file exists: foooverwrite 'foo'?,则表示您犯了一个错误,应该感到难过并且要更加小心。特别是,不要养成y提示是否要覆盖的习惯(可以说,别名应该是alias cp='yes n | cp -i' mv='yes n | mv -i',但是按Ctrl+ C会使输出看起来更好):如果您确实打算覆盖,取消命令,移动或删除输出文件,然后再次运行命令。

同样重要的是,不要养成触发这些安全性的习惯,因为如果这样做,有一天,您将在一台没有配置的计算机上,并且由于您所依赖的保护措施不存在,您将丢失数据。在那里。

noclobber将仅为交互式外壳设置,因为.bashrc.zshrc仅由交互式外壳读取。当然,您不应以影响脚本的方式更改外壳选项,因为它可能破坏那些脚本。


6
rm有一个-I我可以使用并建议的选项:“在删除三个以上文件之前,或者在递归删除时,提示一次;比侵入性小-i,同时仍然可以防止大多数错误”
Reid

9
我强烈建议不要以这种方式重新命名cp和mv。然而,使用-i作为默认的参数对他们来说是一个极好的主意,但它应该适用不同的别名,而不是原始文件(例如我总是把alias copy="cp -i"alias move="mv -i"我的.bashrc)。为什么?由于故障模式。当您使用没有cp / mv别名的计算机或其他用户时,会发生什么?文件可能无意间被覆盖(可能未被检测到!)。带有复制/移动别名的相应故障模式:shell抱怨它无法识别该命令。
hlovdal

1
cp / mv别名还有另外一种失败模式:当编写shell脚本时,习惯于cp =“ cp -i”别名的人可能会写一个cp命令,错误地期望它的行为类似于交互模式,因为没有名称差异。相反,每次我写“ copy somefile / some / where”时,我知道我使用别名而不是直接使用cp命令。而且,即使我应该将副本放入外壳文件中,也会与缺少别名的外壳失败一样。
hlovdal

1
因此,TL; DR的默认建议是将-i参数用于cp和mv,这是极好的选择,但是重用cp和mv名称的建议非常糟糕。真是太糟糕了,我不得不拒绝回答。请更改为使用其他别名,然后我将投票给它。
hlovdal

1
@TomHale您可以使用alias RM='command rm',它会告诉zsh使用外部命令rm而不是别名。这样,您就不必依靠--interactive=never取代先前的内容-i
Adaephon '18年

6

noclobber~/.bashrc(for bash)或~/.zshrc(或更确切地说$ZDOTDIR/.zshrc,对于zsh)中设置shell选项将使其在交互式shell会话中处于活动状态。

非交互式外壳(脚本)不读取这些文件。

Shell选项通常不从父Shell继承。

这意味着您应该能够在那些文件中设置选项,而无需修改现有脚本中的行为,除非脚本明确地提供了那些文件。

我可以看到的唯一缺点是,至少在开始时,您将一再忘记设置了该选项。后来,与所有这类事情一样,>|即使在您实际上可能不想破坏文件的情况下,您也将开始习惯使用(就像使用别名的人rmcp并且始终设置mv-i选项,最终开始总是使用-f在命令行上)。


2
使用bash,如果$SHELLOPTS$BASHOPTS针对shopt那些)在环境中,则选项将被继承(尽管出于这种原因,您通常不希望这样做)。
斯特凡Chazelas

3

不利的noclobber一面是,如果您习惯了活动,那么有一天您将使用一个活动的系统,并且会巧妙地执行一个潜在危险的命令,期望noclobber它会为您节省...而它不会。然后,您必须希望有一个足够近的备份来恢复您破坏的数据,因为您假设首先会要求您进行确认。


当然,有一天,您将使用一个不活跃的系统。当您使用不熟悉的系统时,应格外小心,并确保备份是最新的,然后再执行任何潜在的破坏性操作,例如将输出重定向到文件。
吉尔斯(Gilles)'所以
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.