为什么这些bash前叉炸弹的工作方式不同,&在其中的意义是什么?

丹·K。

我知道普通的叉子炸弹是如何工作的,但是我真的不明白为什么在普通bash叉子炸弹的末尾需要&,以及为什么这些脚本的行为有所不同:

:(){ (:) | (:) }; :

:(){ : | :& }; :

前者会导致CPU使用率激增,然后将我带回到登录屏幕。后者反而只会导致我的系统死机,从而迫使我进行硬重启。这是为什么?两者都不断创建新的流程,那么为什么系统的行为有所不同?

这两个脚本的行为也与

:(){ : | : }; :

即使我希望它们是相同的,这也完全不会引起任何问题。bash手册页指出,管道中的命令已在子shell中执行,因此我被认为::应该已经足够了。我相信,应该在新的子Shell中运行管道,但是为什么会有如此大的变化?

编辑:使用htop并限制进程数量,我能够看到第一个变量创建了一个实际的进程树,第二个变量创建了相同级别的所有进程,而最后一个变量似乎未创建任何进程完全没有。这使我更加困惑,但是也许可以有所帮助?

用户名

警告请勿尝试在生产机器上运行此程序。只是不要。警告:要尝试使用任何“炸弹”,请确保ulimit -u已在使用中。阅读下面的[a]

让我们定义一个函数来获取PID和日期(时间):

bize:~$ d(){ printf '%7s %07d %s\n' "$1" "$BASHPID" "$(date +'%H:%M:%S')"; }

bomb新用户的一个简单的非发行函数(保护自己:请阅读[a]):

bize:~$ bomb() { d START; echo "yes"; sleep 1; d END; } >&2

当调用该函数执行时,其工作方式如下:

bize:~$ bomb
  START 0002786 23:07:34
yes
    END 0002786 23:07:35
bize:~$

date执行该命令,然后打印“是”,睡眠1秒钟,然后关闭命令date,最后,该函数退出并打印新的命令提示符。没有什么花哨。

| 管道

当我们这样调用函数时:

bize:~$ bomb | bomb
  START 0003365 23:11:34
yes
  START 0003366 23:11:34
yes
    END 0003365 23:11:35
    END 0003366 23:11:35
bize:~$

两个命令有时会启动,两个命令会在1秒后结束,然后提示会返回。

这就是pipe|并行启动两个进程的原因

& 背景

如果我们更改通话,则添加结尾&

bize:~$ bomb | bomb &
[1] 3380
bize:~$
  START 0003379 23:14:14
yes
  START 0003380 23:14:14
yes
    END 0003379 23:14:15
    END 0003380 23:14:15

提示将立即返回(所有操作都发送到后台),并且两个命令将像以前一样执行。请注意在[1]该过程的PID之前打印的“作业编号”的值3380稍后,将打印相同的数字以指示管道已结束:

[1]+  Done                    bomb | bomb

那是效果&

这就是&:加快进程启动速度的原因。

更简单的名字

我们可以创建一个简单b地执行两个命令的函数输入三行:

bize:~$ b(){
> bomb | bomb
> }

并执行为:

bize:~$ b
  START 0003563 23:21:10
yes
  START 0003564 23:21:10
yes
    END 0003564 23:21:11
    END 0003563 23:21:11

请注意,我们;在的定义中使用了no b(换行符用于分隔元素)。但是,对于一行上的定义,通常使用;,如下所示:

bize:~$ b(){ bomb | bomb ; }

大多数空格也不是强制性的,我们可以编写等效的空格(但不太清楚):

bize:~$ b(){ bomb|bomb;}

我们还可以使用a&分隔}(并将两个进程发送到后台)。

炸弹。

如果我们使函数咬尾(通过调用自身),则会得到“叉子炸弹”:

bize:~$ b(){ b|b;}       ### May look better as b(){ b | b ; } but does the same.

为了使其更快地调用更多功能,请将管道发送到后台。

bize:~$ b(){ b|b&}       ### Usually written as b(){ b|b& }

如果我们将第一个调用追加到必填项之后,;然后将名称更改为:

bize:~$ :(){ :|:&};:

通常写为 :(){ :|:& }; :

或者,以有趣的方式写上另一个名字(一个雪人):

☃(){ ☃|☃&};☃

ulimit(在运行此命令之前应已设置)将使提示在出现很多错误后迅速返回(在错误列表停止时按Enter以获取提示)。

之所以称为“叉子炸弹”,是因为Shell启动子Shell的方式是分叉运行中的Shell,然后使用要运行的命令调用exec()到fork的进程。

管道将“分叉”两个新过程。达到无穷大会炸弹。
或最初被称为兔子的原因是它繁殖得如此之快。


定时:

  1. :(){ (:) | (:) }; time :
    终止
    实数0m45.627s

  2. :(){ : | :; }; time :
    终止
    实0m15.283s

  3. :(){ : | :& }; time :
    真正的0m00.002 s
    仍在运行


您的示例:

  1. :(){ (:) | (:) }; :

    第二次关闭)分隔的}是的更复杂版本:(){ :|:;};:管道中的每个命令无论如何都在子外壳内部被调用。这是什么效果的()

  2. :(){ : | :& }; :

    是更快的版本,没有空格::(){(:)|:&};:(13个字符)。

  3. :(){ : | : }; : ###在zsh中有效,但在bash中无效。

    出现语法错误(以bash表示),在结束之前需要一个元字符}
    如下所示:

     :(){ : | :; }; :
    

[a]创建一个新的干净用户(我称我为bize)。在控制台中登录到该新用户sudo -i -u bize,或者:

$ su - bize
Password: 
bize:~$

检查然后更改max user processes限制:

bize:~$ ulimit -a           ### List all limits (I show only `-u`)
max user processes              (-u) 63931
bize:~$ ulimit -u 10        ### Low
bize:~$ ulimit -a
max user processes              (-u) 1000

仅使用10个作品,就只有一个单独的新用户:bize它使调用killall -u bize和摆脱系统大多数(不是全部)炸弹变得更加容易请不要问哪个仍然有效,我不会告诉您。但是仍然:相当低但是出于安全考虑,请适应您的系统
将确保“叉子炸弹”不会使您的系统崩溃

进一步阅读:

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么这些语句在JavaScript中的工作方式不同?

来自分类Dev

为什么“ *”在不同命令中的工作方式不同?

来自分类Dev

为什么is_invocable与参考参数的工作方式不同?

来自分类Dev

为什么is_invocable与参考参数的工作方式不同?

来自分类Dev

为什么 IIf 的工作方式与 If/Then/EndIf 不同?

来自分类Dev

为什么“json_encode()”的工作方式不同?

来自分类Dev

推荐流程的工作方式是什么?

来自分类Dev

为什么前叉炸弹没有使Android崩溃?

来自分类Dev

这些查询及其工作方式有什么区别?

来自分类Dev

ACE互斥锁如何工作,为什么ACE线程互斥锁工作方式不同?

来自分类Dev

为什么同一JAVA程序在Windows和Linux等不同平台上的工作方式不同?

来自分类Dev

为什么同一JAVA程序在Windows和Linux等不同平台上的工作方式不同?

来自分类Dev

Python-为什么find和index方法的工作方式不同?

来自分类Dev

为什么AnnotationPresent在Java 7和Java 8之间的工作方式不同?

来自分类Dev

为什么在Java中if(Boolean.TRUE){...}和if(true){...}的工作方式不同

来自分类Dev

在C语言中,为什么包含逗号(,)运算符的expression(Statement)的工作方式不同

来自分类Dev

为什么从Java 9中的Java 8确实String.replaceAll()工作方式不同?

来自分类Dev

为什么此相关子查询在Oracle和SQL Server中的工作方式不同

来自分类Dev

为什么在数组的值情况下比较的工作方式不同

来自分类Dev

为什么某些表达式的sizeof运算符工作方式不同?

来自分类Dev

为什么此处的管道和重定向工作方式不同?

来自分类Dev

为什么Math.Round()在C#中的工作方式不同

来自分类Dev

为什么--var和var-1的工作方式不同?

来自分类Dev

SourceTree Push计数工作方式不同,我不知道为什么

来自分类Dev

从管道读取时,为什么“ sed q”的工作方式有所不同?

来自分类Dev

为什么列表和字符串上的方法在python中的工作方式不同

来自分类Dev

为什么scala.beans.beanproperty在Spark中的工作方式有所不同

来自分类Dev

为什么“perl -F”与“perl -F<space>”的工作方式不同

来自分类Dev

为什么“while”与“for”的工作方式不同,但具有继续状态

Related 相关文章

  1. 1

    为什么这些语句在JavaScript中的工作方式不同?

  2. 2

    为什么“ *”在不同命令中的工作方式不同?

  3. 3

    为什么is_invocable与参考参数的工作方式不同?

  4. 4

    为什么is_invocable与参考参数的工作方式不同?

  5. 5

    为什么 IIf 的工作方式与 If/Then/EndIf 不同?

  6. 6

    为什么“json_encode()”的工作方式不同?

  7. 7

    推荐流程的工作方式是什么?

  8. 8

    为什么前叉炸弹没有使Android崩溃?

  9. 9

    这些查询及其工作方式有什么区别?

  10. 10

    ACE互斥锁如何工作,为什么ACE线程互斥锁工作方式不同?

  11. 11

    为什么同一JAVA程序在Windows和Linux等不同平台上的工作方式不同?

  12. 12

    为什么同一JAVA程序在Windows和Linux等不同平台上的工作方式不同?

  13. 13

    Python-为什么find和index方法的工作方式不同?

  14. 14

    为什么AnnotationPresent在Java 7和Java 8之间的工作方式不同?

  15. 15

    为什么在Java中if(Boolean.TRUE){...}和if(true){...}的工作方式不同

  16. 16

    在C语言中,为什么包含逗号(,)运算符的expression(Statement)的工作方式不同

  17. 17

    为什么从Java 9中的Java 8确实String.replaceAll()工作方式不同?

  18. 18

    为什么此相关子查询在Oracle和SQL Server中的工作方式不同

  19. 19

    为什么在数组的值情况下比较的工作方式不同

  20. 20

    为什么某些表达式的sizeof运算符工作方式不同?

  21. 21

    为什么此处的管道和重定向工作方式不同?

  22. 22

    为什么Math.Round()在C#中的工作方式不同

  23. 23

    为什么--var和var-1的工作方式不同?

  24. 24

    SourceTree Push计数工作方式不同,我不知道为什么

  25. 25

    从管道读取时,为什么“ sed q”的工作方式有所不同?

  26. 26

    为什么列表和字符串上的方法在python中的工作方式不同

  27. 27

    为什么scala.beans.beanproperty在Spark中的工作方式有所不同

  28. 28

    为什么“perl -F”与“perl -F<space>”的工作方式不同

  29. 29

    为什么“while”与“for”的工作方式不同,但具有继续状态

热门标签

归档