Немо не просит, чтобы подтверждение на удалило

ВНИМАНИЕ! НЕ ПЫТАЙТЕСЬ ЗАПУСТИТЬ ЭТО НА ПРОИЗВОДСТВЕННОМ МАШИНЕ. ТОЛЬКО НЕ. Предупреждение: чтобы попробовать любые "бомбы", убедитесь, что используется ulimit -u . Читайте ниже [a] .

Давайте определим функцию для получения PID и даты (времени):

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

Простая, не вызывающая проблем бомба функция для нового пользователя (защитите себя: прочтите [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 секунду, затем закрытие команды дата , и, наконец, функция завершает печать новой командной строки. Ничего фантастического.

| pipe

Когда мы вызываем функцию следующим образом:

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 секунду и затем подсказка возвращается.

Это причина того, что канал | запускает два процесса параллельно.

& background

Если мы изменим вызов, добавив окончание & :

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 (символы новой строки использовались для разделения элементов). {{ 1}} Однако для определения в одной строке обычно используется ; , например:

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

Большинство пробелов также не являются обязательными, мы можем написать эквивалент (но менее четкий) :

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

Мы также можем использовать и , чтобы разделить } (и отправить два процесса в фоновый режим).

Бомба.

Если мы заставим функцию кусать свой хвост (вызывая себя), мы получим «вилочную бомбу»:

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 () для разветвленного процесса с командой для запуска.

Канал «разветвляет» два новых процесса. Если делать это до бесконечности, возникает бомба.
Или кролик, как первоначально называли, потому что он так быстро размножается.


Время:

  1. : () {(:) | (:)}; время:
    Прервано
    действительное 0m45.627s

  2. : () {: | :; }; время:
    Прервано
    реальное значение 0 мин. 15 мин.283s

  3. : () {: | : &}; time:
    real 0m00.002 s
    Все еще выполняется


Ваши примеры:

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

    Где второе закрытие ) отделяет } является более сложной версией : () {: |:;};: .Каждая команда в конвейере в любом случае вызывается внутри суб-оболочки. Это результат () .

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

    Быстрая версия, написанная без пробелов: : () {(:) |: &};: (13 символов).

  3. : () {: | :}; : ### работает в zsh, но не в bash.

    Имеет синтаксическую ошибку (в bash), метасимвол необходим перед закрывающим } ,
    следующим образом:

    : () {: | :; }; : 
      

[a] Создайте нового чистого пользователя (я назову своего bize ). Войдите в систему под этим новым пользователем в консоли либо sudo - i -u bize или:

$ su - bize
Password: 
bize:~$

Проверить и затем изменить максимальное количество пользовательских процессов ограничение:

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 и избавляет систему от большинства (не всех) бомб. Пожалуйста, не спрашивайте, какие из них еще работают, я не скажу. Но все же: Достаточно мало, но на всякий случай адаптируйтесь к вашей системе .
Это гарантирует, что "вилочная бомба" не разрушит вашу систему .

Дополнительная литература:

2
11.04.2015, 23:35
1 ответ

Эта функция еще не существует для Nemo. Пожалуйста, сделайте комментарий, чтобы повысить приоритет этого запроса, здесь: https://github.com/linuxmint/nemo/issues/1135.

1
27.01.2020, 22:21

Теги

Похожие вопросы