ПРЕДУПРЕЖДЕНИЕ НЕ ПЫТАЙТЕСЬ ЗАПУСТИТЬ ЭТО НА ПРОИЗВОДСТВЕННОЙ МАШИНЕ. ПРОСТО НЕ.
Предупреждение: чтобы попробовать любые «бомбы», убедитесь, что они ulimit -u
используются. Читайте ниже [а] .
Давайте определим функцию для получения 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 секунду, а затем приглашение возвращается.
Это причина того, что труба |
запускает два процесса параллельно.
& фон
Если мы изменим вызов, добавив окончание &
:
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
Обратите внимание, что мы не использовали ;
в определении 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, когда список ошибок остановится, чтобы получить приглашение).
Причина, по которой это называется «бомба-вилка», заключается в том, что оболочка запускает под-оболочку путем разветвления работающей оболочки и последующего вызова exec () для разветвленного процесса с командой для запуска.
Труба будет "раскошелиться" на два новых процесса. Выполнение этого до бесконечности вызывает бомбу.
Или кролик, как его первоначально называли, потому что он так быстро размножается.
Сроки:
:(){ (:) | (:) }; time :
Прекращено
реальное 0m45.627s
:(){ : | :; }; time :
Прекращено
реальное 0m15.283s
:(){ : | :& }; time :
реальный 0m00.002 с
Все еще работает
Ваши примеры:
:(){ (:) | (:) }; :
Где второе закрытие )
отделяет, }
является более сложной версией :(){ :|:;};:
. В любом случае каждая команда в канале вызывается внутри вложенной оболочки. Который является эффектом ()
.
:(){ : | :& }; :
Это более быстрая версия, написанная без пробелов: :(){(:)|:&};:
(13 символов).
:(){ : | : }; :
### работает в 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
и избавление системы от большинства (не всех) бомб. Пожалуйста, не спрашивайте, какие еще работают, я не скажу. Но все же: довольно низкий, но на безопасной стороне, адаптироваться к вашей системе .
Это гарантирует, что «вилочная бомба» не разрушит вашу систему .
Дальнейшее чтение:
:(){ : | :; }; :