命令行和脚本是危险的。 用rm -rf写一个错字,你处在一个受到伤害的世界里。 在运行导入脚本的同时,将数据库名称与数据库名称混淆起来,并将其绑定(如果它们位于同一台服务器上,这并不好,但会发生)。 同样的,注意到一些命令之后,服务器名称并不是你认为的那样。 你必须尊重孔霍克 。
在运行有风险的命令之前,我有一些小小的仪式 – 比如对我所在的服务器进行三重检查。 这里有一篇关于RM安全的有趣文章 。
什么小仪式,工具和技巧让你在命令行上安全? 我的意思是客观的事情,比如“先运行ls foo *,看看输出,然后用rm -rfreplacels以避免运行rm -rf foo *或类似的东西”,而不是“确定你知道什么命令会做“。
一个很好的方法就是在你的shell上使用不同的背景颜色来生成/登台/testing服务器。
在开始之前,请记住退出计划。
我有一些低技术解决scheme,其中一些。
我制定了一个习惯做以下事情(当计划以root身份工作时):
sudo su - root切换到root用户。 我这样做是心理准备,提醒我,我已经精神上走进了一个非常危险的地区,我应该随时保持警惕和警惕。 听起来很有趣,这个小小的仪式本身通过强化我不能不小心 ,为我节省了很多的痛苦。 sudo , 不是因为我是BOFH ,而是因为没有准备和训练,就像给猴子上了一个装满枪的枪。 开始的时候有趣有趣,直到猴子看到桶子,挤压… 当使用rm时,我总是先cd到目录,然后使用./的前缀来确保目录是正确的,即
cd /usr/some/directory ; rm ./targetfile
或者我指定文件的整个path
rm /usr/some/directory/targetfile
这是一个PITA,但是…比对不起更安全。
这一个是特定于Windows Powershell的。
作为一项政策,我们在每台服务器上添加以下机器profile.ps1。 这确保以下情况是正确的:
$ currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity] :: GetCurrent())
&{
if($ currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole] :: Administrator))
{
(获取主机).UI.RawUI.Backgroundcolor =“暗红色”
明确主机
写主机“警告:PowerShell以pipe理员身份运行。
}
$ utilities = $ null
如果([IntPtr] :: size * 8 -eq 64)
{
$ host.UI.RawUI.WindowTitle =“Windows PowerShell(x64)”
$ utilities =“$ {env:programfiles(x86)} \ Utilities”
}
其他
{
$ host.UI.RawUI.WindowTitle =“Windows PowerShell(x86)”
$ utilities =“$ {env:programfiles} \ Utilities”
}
if((Test-Path $ utilities) - and!($ env:path -match $ utilities.Replace(“\”,“\\”)))
{
$ env:path =“$ utilities; $ {env:path}”
}
}
function提示
{
if($ currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole] :: Administrator))
{
如果(!$ host.UI.RawUI.WindowTitle.StartsWith(“Administrator:”))
{$ Host.UI.RawUI.WindowTitle =“Administrator:”+ $ host.UI.RawUI.WindowTitle}
}
'PS'+ $(if($ nestedpromptlevel -ge 1){'>>'})+'>'
}
我可以同意所有上述的答案,但我必须强调这个非常非常重要的提示:
知道什么时候避免多任务。
我确定我所在系统的主机名在bash(或其他shell)提示符下。 如果我是chroot,我肯定也会以某种方式进入。
我曾经在另外一个活的Linux发行版中安装了一个Gentoo系统,并且意外地在错误的shell中运行了一个非常具有破坏性的命令(无法回想一下它是什么样的ATM – 一些rm变体),导致一系列的活动系统被删除,而不是来自chroot内的东西。 从那时起,我一直这样做
export PS1="(chroot) $PS1"
每当我在一个chroot工作。
在更改服务器之前,有几件重要的事情需要注意:
确保我在正确的服务器上
注意**有多less人会受此行为的影响*(如果您犯了错误)
在input“input”键之前,请注意撤消的可能性
问问你自己,这个命令是否有可能断开你的会话 (fw规则,坏的关机等)。 确保你有一个故障转移回来(特别是如果你是异地)
如果你还没有做到这一点别名rm -r -i
规则1 – 进行备份
规则2 – 切勿在标准命令中添加“保密”包装,制作自己的版本,但不要接pipe名称,当你在没有设置的系统上时,它会咬你。
像root和(部分)目录树等不同颜色的提示技巧是很好的帮手,但同样,确保你可以在没有它们的情况下工作。
这看起来可能与直觉相反,但是最好的命令行安全提示是: 如果一个GUI模式的select是可用的和实用的,则使用IT 。
为什么? 非常简单。 graphics用户界面模式通常有一个内置的安全网,forms是“警告 – 你要咆哮freeblefrop,你确定要这样做吗? 即使没有,也会让你放慢脚步,给予思考时间更多的空间。 它可以让你仔细检查选项之前,提交给他们,你可以截图之前和之后的状态,它可以保护你免受错别字; 所有好的,有用的和有益的东西。
在可怕的“rm -rf”的经典案例中,你是否认为从GUI或CLI意外发出它更容易?
最后,诉诸GUI并不是什么好事。 它不会完全防止重大灾害; 就像在CLI中一样,可以在GUI中触发快乐; 但是如果它能够拯救你,那么它一旦被certificate是值得的。
使用常识,不要运行你不明白的命令。 这是很好的build议。 如果你想要写出你传递给rm的所有东西的绝对path,或者通过sudo运行任何东西,那么就自由了。 那么我宁愿su -c。 至less它不会caching密码。 如果没有密码validation,任何普通用户都可以使用root权限运行,我感觉不太舒服。
有几件事情可以放在你的〜/ .bashrc中,让事情变得更安全一点,比如:
alias srm='rm -i'
让你有一个安全的替代rm,…
但最后,你可能会总是搞砸了。 有一天,我有一个已经失效的configuration脚本,我的整个/ usr / bin文件夹,打破了几件事情。 是的,一个简单的“安装”任何types的软件的错误,可能会打破你的系统。 无论你做什么,你永远不会安全。 我所得到的是,最重要的是:
保持定期备份。
而不是别名rm到rm -i,用别名说删除或saferemove(并将其用作首选删除工具)不是更好。 然后当你使用一个没有这个设置的盒子时,不会造成伤害。
确保你永远不会运行你在网上find的命令,除非你完全明白他们在做什么。
你的系统可能与海报有所不同,这可能会造成一个伤害的世界。
从Unix / Linux的angular度来看,一个明显的命令行安全就是正确使用root帐户。
rm -rf作为root通常比用户更危险,使用sudo等内置的东西而不是rootlogin是至关重要的。 一个不错的简单whoami通常会帮助精神分裂症或多重人格。
这和prepending对任何文件切换命令的回声,特别是如果你想确保你有一个glob或正则匹配的权利。
如果你杀了你的主要会话,或者做了一些愚蠢的事情来locking它,那么在你正在使用的机器上build立一个辅助连接可能会很方便。
这样你仍然可以进入机器,并可以杀死你的主要会话。
上面的大多数评论都是指rm,但是我也用其他命令做了一些愚蠢的事情。
ifconfig取下networking – 哎哟,这需要物理存在来解决。
至于脚本,我通常在两个窗口中工作。 第一个我用来写脚本,第二个testing每一行,因为我写它。 慢慢地仔细地做,我可以确保每一行都按我所期望的那样工作,当我编写代码时,注意保持相同的variables等等。
就个人而言,我并没有发现额外的提示,像rm -i真的有帮助。 当我厌倦,强调等等时,我会犯大部分的错误,而这些时候我只是一味地嘲笑你而忽视提示。 不好的做法也许。
如果你使用bash,试试这个:
TMOUT=600
在/root/.bashrc或类似的。 它会在10分钟后自动将您注销,这样可以减less您不小心打开并input某些内容的根端子的机会。
是的,我知道你应该使用sudo来执行root命令 – 这只是一个额外的安全网,以防你决定玩一天冒险。
# Allow only UPDATE and DELETE statements that specify key values alias mysql="mysql --safe-updates"`
如果您曾经使用过mysql命令行,那么强烈推荐别名。
我不使用ls,而是使用echo,因此在shell扩展了所有内容后,我可以看到完整的命令。 此外,总是使用双引号variables来表示文件,以便您的文件可以使用可能具有制表符或空格的文件名。
尽可能避免* glob作为自己的参数。 即使我的意思是“删除这个目录中的所有东西”,我也试图更具体一点,也就是说。 rm *.php 。 如果我不小心将另一个目录中的相同命令从历史logging中删除,那么这是先发制人的损坏控制。
让你思考你在做什么的一个好方法是把这样的东西添加到root的bashrc(cshrc,whatever):
unset PATH
那样,你必须做/ bin / rm而不是“rm”。 那些额外的angular色可能会让你思考。
对于复杂的正则expression式,特别是“查找”命令把echo放在前面,并将它们捕获到一个文件中。 然后你可以检查你是否真正删除/移动/等到你认为你是什么之前执行文件与“源”。
手动添加正则expression式没有select的边界情况也很方便。
对其他一些post稍微meta:我使用首先build议的通常的echo / ls步骤,以确保该命令是select我想要的文件集或由shell解释为预期的。
但是之后我使用shell的命令历史编辑function来检索以前的命令,并且只修改需要改变的部分。
单独input每个命令都无济于事
$ ls *.bak $ echo rm *.bak $ rm * .bak
…因为我意外地在最后一行input了空格,并删除了所有的文件。 我总是检索前一行,只是删除'回声'。
根用户:
除非必须,否则不要成为根。
如果供应商表示需要以root身份运行,请告诉他们您是客户,并且您希望以非root身份运行它。
现成的软件包有多less只是因为它更容易?
习惯:
永远不要用“*”删除而不去查看三次最好是build立使用ls -l TargetPattern的习惯,然后使用“rm!$”。 最大的威胁不在于你认为自己在哪里。 我经常像'ls'一样input'hostname'!
拐杖:
一个标准提示可以帮助很多人,比如“alias rm ='rm -i'”这样的别名,但是我经常没有完全控制我所在的机器,所以我只用一个expect包装脚本来设置你的path,提示,并用'-i'
发现问题:
使用完整path有助于,但是在不可能的情况下,请进入更安全的位置,并使用'&&'确保'cd'成功,然后再进行查找,删除,tar,untar等操作:
例如: cd /filesystema && tar cf - | ( cd /filesystemb && tar vxf -) cd /filesystema && tar cf - | ( cd /filesystemb && tar vxf -)
在这种情况下,使用'&&'可以防止tar文件被提取出来(尽pipe在这种情况下'rsync'会更好)
删除:
如果可以帮助,请不要recursion删除,特别是在脚本中。 find并删除-type f和-name'模式'我仍然生活在恐惧喂养'没有'xargs …焦油和untar移动的东西周围(使用rsync代替)
如果您使用操作系统的多个变体,请注意语法上的差异; 一个unix变体的安全性是非常危险的。
例如:killall
Linux / FreeBSD / OSX – 杀死所有匹配参数的进程。 例如:“killall apache”杀死所有的apaches,只留下所有其他进程。
Solaris – 杀死所有进程。 不完全是。 从手册页 :killall被shutdown(1M)用来终止所有与closures过程没有直接关系的活动进程。
代替
rm foo*
使用
rm -i foo*
这对less数文件来说是实用的,但是与整个压缩包不同。 这就是为什么别名会妨碍你的方式。
首先使用echo运行命令是一个好主意,但仍然容易出现拼写错误。
尝试使用扩展名,例如!$。
echo foo* rm -rf !$
!$扩展到最后一个命令的最后一个单词,所以它相当于
echo foo* rm -rf foo*
还有!*,扩展到最后一个命令的所有参数。
事实上,如果你愿意,你可以这样做
echo rm -rf foo* !*
(如果您使用的是ksh,而不是bash,则可以inputEsc +句点来代替最后一个单词。)
在类似的情况下:
ls * .php
回声rm * .php
rm * .php
您可以使用replace运算符,如下所示:
$ ls * .php
<dir listing>
$ ^ ls ^ echo rm(用前面的命令中的ls代替echo rm,保持命令行的其余部分一致)
$ ^ echo rm ^ rm(用rmreplaceecho rm,因此你不必重新input* .php并在错误的时间input空格)
对于那些不熟悉的人,^ = shift-6。
使用bash并设置PS1 ='\ u @ \ h:\ w>'。 这扩展到用户名@主机名:/完整/工作/目录/path>正如其他答案中所提到的,你可以使用期望设置环境,无论你login,如果你不能更新.profile或.bash_profile文件。 虽然改变背景颜色很容易是最好的答案:-)
是啊。 通过IRC发送给某人一个文件的这个古老的技巧命名为“-rf”,所以它最终在他们的目录中。 稍后有一个“rm -rf”(而不是“rm -rf”),随着他们学习一个关于不以root身份运行IRC的严峻教训,随之而来的是大笑声。
而不是使用rm -rf <dir>将-rf放在最后,如下所示: rm <dir> -rf 。 把它瞄准之后,在你开火之前,把它看作是安全的。 这样,如果您在input目录名称(或使用制表符完成)的同时有一个input键,并且具有类似命名的目录,那么您将受到保护。