Столь же странный, как это, проблема просто исчезла. Я не коснулся файлов данных или чего-либо... Поля просто не появляются больше
В результате канала в x | y
, подоболочка создается для содержания конвейера как части группы приоритетного процесса. Это продолжает создавать подоболочки (через fork()
) неограниченно долго, таким образом создание fork-бомбы.
$ for (( i=0; i<3; i++ )); do
> echo "$BASHPID"
> done
16907
16907
16907
$ for (( i=0; i<3; i++ )); do
> echo "$BASHPID" | cat
> done
17195
17197
17199
Ветвление на самом деле не происходит, пока код не выполняется, однако, который является заключительным вызовом :
в Вашем коде.
Чтобы демонтировать, как fork-бомба работает:
:()
- определите новую вызванную функцию :
{ :|: & }
- функциональное определение, которое рекурсивно передает функцию вызова по каналу в другой экземпляр функции вызова в фоновом режиме:
- вызовите функцию fork-бомбыЭто имеет тенденцию не быть слишком интенсивно использующим память, но это высосет PIDs и использует циклы ЦП.
Последний бит кода, ;:
выполняет функцию :(){ ... }
. Это - то, где ветвление происходит.
Точка с запятой завершает первую команду, и мы запускаем другой, т.е. вызываем функцию :
. Определение этой функции включает вызов в себя (:
) и вывод этого вызова передается по каналу к фоновой версии :
. Это поддерживает процесс неограниченно долго.
Каждый раз Вы вызываете функцию :()
Вы вызываете функцию C fork()
. В конечном счете это исчерпает все идентификаторы процесса (PIDs) в системе.
Можно выгрузить |:&
с чем-то еще так можно понять то, что продолжается.
В одном окне терминала делают это:
$ watch "ps -eaf|grep \"[s]leep 61\""
В другом окне мы выполним немного измененную версию fork-бомбы. Эта версия попытается отрегулировать себя так, мы можем изучить то, что она делает. Наша версия будет спать в течение 61 секунды прежде, чем вызвать функцию :()
.
Также мы будем фон начальный вызов также, после того, как он будет вызван. Ctrl + z, затем введите bg
.
$ :(){ sleep 61; : | : & };:
# control + z
[1]+ Stopped sleep 61
[2] 5845
$ bg
[1]+ sleep 61 &
Теперь, если мы работаем jobs
команда в начальном окне мы будем видеть это:
$ jobs
[1]- Running sleep 61 &
[2]+ Running : | : &
После нескольких минут:
$ jobs
[1]- Done sleep 61
[2]+ Done : | :
Между тем в другом окне, куда мы работаем watch
:
Every 2.0s: ps -eaf|grep "[s]leep 61" Sat Aug 31 12:48:14 2013
saml 6112 6108 0 12:47 pts/2 00:00:00 sleep 61
saml 6115 6110 0 12:47 pts/2 00:00:00 sleep 61
saml 6116 6111 0 12:47 pts/2 00:00:00 sleep 61
saml 6117 6109 0 12:47 pts/2 00:00:00 sleep 61
saml 6119 6114 0 12:47 pts/2 00:00:00 sleep 61
saml 6120 6113 0 12:47 pts/2 00:00:00 sleep 61
saml 6122 6118 0 12:47 pts/2 00:00:00 sleep 61
saml 6123 6121 0 12:47 pts/2 00:00:00 sleep 61
И a ps -auxf
шоу эта иерархия процесса:
$ ps -auxf
saml 6245 0.0 0.0 115184 5316 pts/2 S 12:48 0:00 bash
saml 6247 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
....
....
saml 6250 0.0 0.0 115184 5328 pts/2 S 12:48 0:00 bash
saml 6268 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
saml 6251 0.0 0.0 115184 5320 pts/2 S 12:48 0:00 bash
saml 6272 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
saml 6252 0.0 0.0 115184 5324 pts/2 S 12:48 0:00 bash
saml 6269 0.0 0.0 100988 464 pts/2 S 12:48 0:00 \_ sleep 61
...
...
A killall bash
остановит вещи, прежде чем они выйдут из-под контроля. Выполнение Вашей уборки, этот путь может быть немного жестоким, более добрый более нежный путь, который потенциально не порвет каждый bash
окружите вниз, должен был бы сделать следующее:
Определите, в каком псевдотерминале fork-бомба собирается работать
$ tty
/dev/pts/4
Уничтожьте псевдотерминал
$ pkill -t pts/4
Хорошо каждый вызов bash
и sleep
вызов к функции C fork()
от bash
оболочка от того, куда команда была выполнена.
bash
мог бы работать на отдельных терминалах. Лучше должен был бы использовать pkill -t pts/2
.
– Maciej Piechotka
31.08.2013, 22:25
x | y
, почему там созданная подоболочка? Для моего понимания, когда удар видит apipe
, это выполняетсяpipe()
системный вызов, который возвращается дваfds
. Теперь, command_leftexec
редактор и вывод питаются к command_right, как введено. Теперь, command_rightexec
редактор Так, почемуBASHPID
отличающийся каждый раз? – Abhijeet Rastogi 03.09.2013, 08:21x
иy
2 отдельных команды, работающие в 2 отдельных процессах, таким образом, у Вас есть 2 отдельных подоболочки. Еслиx
выполнения в том же процессе как оболочка, которая означаетx
должно быть встроенное. – jw013 03.09.2013, 23:59