史上最邪恶的shell脚本!没有之一!

微博上的朋友 @马甲与小号告诉我发现了一个奇怪的东西,本着好奇心使人进步(害死猫?)的目的,我去观摩了一番,于是就有了今天这篇文章。

 

这是一个 bash shell 脚本,其中有若干可以整蛊(结仇)你的同事的小技巧——或者说恶作剧。看完之后,感觉不寒而栗,要是谁敢这样整我,我一定和他绝交!

 

警告,切勿在生产环境体验,一切后果自负!

警告,切勿在生产环境体验,一切后果自负!

警告,切勿在生产环境体验,一切后果自负!

 

这个世界怎么了?

 

这个脚本主要由一些别名、函数、环境变量定义组织而成,执行该脚本后,你的 shell 环境就变成了一个光怪陆离的世界。

 

好了,那么我们来看看都发生了什么。

 

注:本脚本适用于 bash 环境,其它 shell 环境有些不支持。

 

可怕的默认编辑器

 

当系统调用默认编辑器来编辑比如 crontab 时,biu 的一下,文件没了!

 

exportEDITOR=/bin/rm;

 

这是将 EDITOR 环境变量定义为 rm而它原本应该是 viemacs nano 体会一下是不是很酸爽

 

学习课堂:

EDITOR 环境变量用于定于系统的默认编辑器,在一些系统内置功能里面,比如编辑 crontab 时,会根据该变量调用默认编辑器。

 

猥琐的制表符(tab

 

当你想用制表符来个自动补全时,你会它非但不干,而且还删除了一个字母,不信邪的你使劲多砸了几个制表符,这下好了,更多的字符被删除了。

 

tset -Qe $'\t';

 

原来是将制表符定义为退格键了。

 

学习课堂:

tset 用于设置终端特征;-e 参数设置擦除字符,缺省为退格字符;-Q 表示不显示设置信息(静默)。

 

莫名退出

 

有时候,执行一个命令就会莫名其妙地退出 shell,只不过是命令有个非 0 的返回状态嘛,为什么会这样?

 

((RANDOM % 10))|| set -o errexit;

 

学习课堂

set -o errexit 等价于 set -e表示有任何错误命令的返回状态非 0 时即退出。

 

啥都看(cat)不了

 

当我想看(cat)一下文件时,它居然就当没听见,到底文件里面有啥啊?

 

alias cat=true;

 

原来是把 cat 定义成 true 命令的别名了 true 命令啥都不干不管你给它什么参数和什么输入它只是静静地返回一个 0 的状态码。

 

学习课堂

true 命令和 false 命令常用于 shell 脚本中。

 

到底是按什么排列的啊

 

好吧,我想看看目录里面有啥文件,于是我输入了 ls,咦?这是什么顺序?我再次输入一遍,怎么回事,列出的文件和目录又是一种顺序,难道它的输出看心情吗?

 

function ls {command ls -$(opts="frStu"; echo ${opts:$((RANDOM % ${#opts})):1})"$@"; }

 

原来它用一个函数重新定义了 ls,所以,真是看心情,你永远不知道它会以什么顺序返回结果。

 

学习课堂:

ls f 选项表示不排序输出(即只按照磁盘存储顺序输出);r 表示反向排序;S 表示按文件大小排序;t 表示按修改时间排序;u 表示按最后访问时间排序。

 

再也不要试着进入目录了

 

当我想进入目录看看时,惊奇的是居然没进去,难道没有自动补全我就输入错了?用前面那个奇奇怪怪的 ls 再次看看时,令人惊恐的是,那个目录!它没有了!!!不信邪的我又重复了这个过程,然后,我就一个子目录也没有了!

 

alias cd='rm-rfv';

 

这该死的,连输入 cd 这么无害的命令都这么可怕!

 

学习课堂:

rm 命令的 -r 表示可删除(非空)目录;-f 表示不需要确认删除;-v 表示删除后显示被删除的文件/目录名称——这里是用来嘲讽我删除了某个目录的吗?

 

还敢用 sudo 权限吗?

 

我很遵守安全守则,从来不用 root 直接登录,凡是管理任务,都用 sudo 来执行。

 

然而,现在无论我用 sudo 执行什么命令,都会马上关机,并将我输入的命令广而告之!这是我被系统讨厌了么?

 

alias sudo='sudoshutdown -P now';

 

学习课堂:

 

shutdown 命令用来关闭系统,-P 参数表示连同电源一起关闭; now 表示马上关机。这之后的参数(在此例中,是原本希望 sudo 执行的命令)会作为关闭前的通知信息,广播给系统上所有在线的用户。

 

我原本想静静,结果世界都静了

 

杂乱的屏幕输出让你厌憎,所以,一个 clear 命令就可以静静了——等等,为什么我的终端崩溃了?然后系统也死机了。

 

aliasclear=':(){ :|:& };:';

 

这是将 clear 命令别名为一个 fork 炸弹了,据说这个是最精简、最难懂的 fork 炸弹了。至于炸弹的效果,嗯,世界都安静了

 

学习课堂:

Fork 炸弹带来的后果就是耗尽服务器资源,使服务器不能正常的对外提供服务,也就是常说的 DoSDenial of Service)。

 

今夕是何年?

 

这光怪陆离的世界啊,让我疑似梦中,那么,现在是什么时候?当然,我肯定不会去翻日历的,输入 date 命令才是我们命令行极客该做的事情。看着返回的日期,我不禁怀疑我的记忆,难道我穿越了么?

 

alias date='date-d "now + $RANDOM days"';

 

学习课堂:

 

date 命令可以显示相对偏移的日期,上述命令中 $RANDOM 的结果是一个随机的整数,也就是说这里的 date 命令会返回若干天之后的日期。

 

如果你有一个鬼马的 CD 驱动器

 

现在 CD 驱动器用的不多了,但是很多机器上还残留着这个咖啡杯托,如果你有幸还有这个东西的话,或许今天它就被鬼怪附体了,一会弹出,一会又收回去,有时候你按下弹出键却毫无反应——当你真的将咖啡杯放上面时,小心,你的咖啡杯会掉下来!

 

CD 盘托当成咖啡杯托是一个笑话,据说某人曾经给电脑厂家打电话:

您好,我想说你们的机器上的咖啡杯托以前挺好用的,可是现在它不动了。

“‘咖啡杯托?那是什么?

就是那个一按按钮就会弹出的托盘啊,放咖啡杯正好,还有合适的凹槽,设计的不错!以前都好好的,现在它不会弹出了。

“……”



N=$[$RANDOM% 3];

    if [[ $N == 0]]; then

        # 几分钟后随即打开或关闭

        sh -c 'sleep$[($RANDOM % 900) + 300]s; while :; do eject -T; sleep $[($RANDOM % 20) + 1]s;done' > /dev/null 2>&1 &

    elif [[ $N == 1]]; then

        # 要么,死活打不开

        sh -c 'while :;do eject -t; eject -i on; sleep 0.1s; done' > /dev/null 2>&1 &

    else

        # 要么,读取变得极慢(1 倍速),需要循环的原因是弹出后就需要重新设定。

        sh -c 'set +oerrexit; while :; do eject -x 1; sleep 1s; done' > /dev/null 2>&1&

    fi;

 

学习课堂:

 

eject 是操作 CD 驱动器的命令行,记得当年有位第一次接触 SUN Solaris 的同事问我,这 CD 怎么打开啊?我默默地输入了 eject在同事愕然的眼光中不带走一丝云彩轻轻地离开。

 

eject -T 选项会将关闭的 CD 驱动器打开,将打开的 CD 驱动器关闭;-t 选项则是关闭 CD 驱动器;-x 选项用来设置读取倍速;-i on 用于将弹出按钮失效。

 

冰川时代

 

突然地,某个你已经打开的程序冻结了,也许是你的浏览器、也许是你正写了一半的文档,所以,随时保存文档是个好习惯吗?

 

sleep $[ ($RANDOM % 100 )  + 1 ]s && kill -STOP $(ps x -o pid|sed1d|sort -R|head -1) &

 

学习课题:

 

sleep 就不用解释了,这代表暂停若干秒。

 

通过上述 ps 命令会会随机选出(sort 命令的 -R 选项)一个你的进程号,然后由 kill 命令发送 STOP 信号给它。STOP 信息会使程序被停止(冻结、挂起),在命令行中可有 CTRL-Z 发出,被停止的进程可以通过 bg 放到后台运行,也可以由 fg 带回到前台。

 

一个还是两个?

 

当我想复制一个文件到另外一个地方时,咦?原来的那个哪里去了?

 

alias cp='mv';

 

还好,还好,你总是还有一个副本的,这总算是不幸中的大幸了。

 

学习课堂:

cp mvmv 还是 mv

 

永不停止的工作

 

打完收工,你总是要退出(exit)你的 shell 的,但是一直退不出是什么意思?

 

alias exit='sh';

 

学习课堂:

 

exit 命令别名为 sh ,这样输入 exit 命令后不是退出当前 shell,而是有进入了一个新的子 shell,想退出不干?没门!

 

到底是哪行?

 

会用 grep 的你,应该知道 -n 参数可以告诉你所匹配的行的行号,但是随机乱变的行号是什么鬼?我讨厌随机!

 

function grep {command grep "$@" | awk -F: '{ r = int(rand() * 10); n = $1; $1 =""; command if (n ~ /^[0-9]+$/) { o = n+r } else { o = n }; print o":" substr($0, 2)}'; }

 

grep 命令的 -n 用于输出匹配的行的行号,上述函数将 grep 定义为一个输出的行号完全不可预测的程序。

 

世界是反着的

 

你脚本也总是出各种匪夷所思的问题,而且你还不知道什么地方出了问题。这一切都要怪你进入了一个即是的世界。

 

alias if='if !'for='for !' while='while !';

 

iffor while 所检测的条件定义为反,我不知道这个世界可以疯狂到这个地步!

 

学习课堂:

if for while 是用于 shell 脚本中做逻辑判断和循环的语句,! 表示对表达式逻辑取反。

 

想执行命令?没门!

 

当你输入了一个命令之后,用小指轻轻地、优雅地,按下右侧的那个小小的回车键,满心以为会爆发出绝世高手的风范。然而……并没有,非但没有,你输入的命令还被删除了一个字符!懵逼的你以为用力太轻了,再次敲击后发现又被删除了一个!!!

 

记得有一个电影,危急情况下,当别人把键盘递给一位即将闭眼的黑客时,他只是轻轻按下了那个回车

 

bind'"\C-J":"\C-?"';

bind'"\C-M":"\C-?"';

 

学习课堂:

 

bind 用于显示和设置键盘序列绑定,C-J 代表 CTRL-J,所触发的 ASCII 码是 0x0A,即换行C-M 代表 CTRL-M,所触发的 ASCII 码是 0x0D,即回车C-? 代表 CTRL-?,所触发的 ASCII 码是 0x7F,即退格。也就是说,你按下的回车键,会被映射为退格键。关于 ASCII 控制字符,可参见:http://ascii-table.com/control-chars.php。也可以使用 showkey -a 命令来检验你按下的键的键值(CTRL-D 退出)。

 

好的,但是我不干

 

你说要,但是你的身体却说不要。明明应该应答 yes,但是却实际上拒绝了。

 

aliasyes="yes n";

 

学习课堂:

yes 命令常用于脚本中应答 y,但是这里重定义了 yes 的结果。这是身口不一么?

 

我要编辑文件

 

当我用 vim 打开一个文件时,为什么什么都没发生?

 

aliasvim="vim +q";

 

学习课堂:

vim 可以用 + 来跟上要在 vim 里面执行的命令,这里 +q 表示退出 vim

 

最后,别想回到正常的世界

 

好吧,我明白了,都是 alias 捣的鬼,我要取消它们。什么?取消也无效了?

 

aliasunalias=false;

aliasalias=false;

 

学习课堂

alias unalias 别名为 false那你就不能执行 alias 的功能了。

 

让我回到真实的世界吧!

 

好了,我已经受够了这个疯狂是世界了。其实,上面这些别名,都是可以通过输入命令的全路径来绕开别名的——只是一般人不会这样输入。

 

想要整蛊你的同事那就将这个脚本https://github.com/mathiasbynens/evil.sh/blob/master/evil.sh 放到他的机器上并在他的 .bash_profile 的末尾加入 source~/evil.sh 即可。当然,你要这么做之前,要有友尽的心理准备。

 

感谢这个邪恶的脚本的贡献者: Mathias Bynens Jan Moesen 等人 ;

 

 

 

 

 

分割线
感谢打赏
江西数库信息技术有限公司
YWSOS.COM 平台代运维解决方案
 评论
 发表评论
姓   名:

Powered by AKCMS