Що означає ця загадкова команда Баша?


23

Я читав попередження форуму Ubuntu про шкідливі команди і знайшов цей цікавий дорогоцінний камінь:

:(){ :|:& };:

ПОПЕРЕДЖЕННЯ . Вищевказаний код призведе до збою вашої машини, якщо у вас немає чітких обмежень (якщо ви, мабуть, цього не зробите), що призведе до жорсткого перезавантаження.

Розглянемо цей код подібним до запущеного sudo rm -rf /.

Але що це означає? Навіть зі своїм досвідом програмування я ніколи не бачив такої загадкової команди, яка не є мовою складання.


16
Додатковий момент: це насправді не схоже на sudo rm -rf /. Ця команда видаляє всі ваші файли; цей просто засмічує ресурси машини, поки він не стане непридатним, і вам доведеться перезапустити.
jtbandes

@jtban: Потім відредагуйте його. Обидва фрагменти коду - це те, що я вважаю "небезпечним" для запуску. Так, sudo rm -rf /це більш небезпечно, але я бачив, як люди виконують це на віддалених серверах, "просто хотів побачити, що це робиться ", де вам важко перезапустити без доступу до панелі управління.
Джош К

7
це емотибом: P
RCIX,

Зауважте, це могло бути arbitrary_name(){ arbitrary_name|arbitrary_name& };arbitrary_name. Назва :не тільки робить цю команду короткою та виразною, але й перетворює :вбудований, який нічого не робить, у функцію, яка робить багато . Якщо ви прокрадете його визначення :(){ :|:& }в чуже оточення і даєте йому залишитися там, воно вдарить, коли жертва цього найменше очікує .
Каміль Маціоровський

Відповіді:


40

Це, як ви сказали, forkbomb. Що він робить - це визначити функцію, а потім викликати її. Функція викликається :.

Давайте назвемо це, forkbombщоб ми могли краще побачити, що відбувається:

forkbomb(){ forkbomb|forkbomb& };forkbomb

Як ви бачите, і, напевно, здогадуєтесь із досвіду програмування, перша частина - це визначення функції ( forkbomb(){ ... }), а сама остання :- це те, де функція викликається ( ;просто відокремлює висловлювання в Bash).

Тепер, що ця функція робить? Якщо ви знайомі з Bash, ви знаєте, що |персонаж передає стандартний вихід однієї команди / програми на стандартний вхід іншої. В основному, :|:запускає два екземпляри функції (саме тут вона "розщеплюється").

І тоді магія: &кладе ці команди на задній план, дозволяючи повернути оригінальну функцію, в той час як кожен екземпляр вил, поки корів не повернеться додому на задньому плані, таким чином використовуючи всі свої ресурси та знімаючи систему (якщо у неї немає обмежень накладене на нього).


1
Чудова відповідь! Я не розумів, що ти можеш використовувати: як ім'я функції. Перейменування допомагає. Прийму через 3 хвилини.
TheLQ

1
+1 Класно ... Чудове пояснення. Це подібно переповненню стека для роботи програми перегляду завдань ОС. Це насправді виходить з ладу ядро ​​чи воно просто з'їдає ресурси, поки воно просто не стане занадто нестерпним у використанні?
Еван Плейс

Я не думаю, що це насправді вибиває ядро, принаймні, не безпосередньо. Він просто продовжує створювати експоненціально більше процесів, кожен з яких займає процесор і пам'ять, а з процесором, який намагається впоратися з усіма ними, це справді стає неможливо використовувати. Можливо, ядро ​​врешті-решт виходить з ладу під навантаженням (я не впевнений), але до цього воно буде непридатним.
jtbandes

3
Не забудьте пояснити фінал :, який фактично виконує функцію!
Phoshi

@Phoshi: думав, що я це зробив, але редагую, щоб уточнити!
jtbandes

9

Взято з статті Вікіпедії Forkbomb :

:()      # define ':' -- whenever we say ':', do this:
{        # beginning of what to do when we say ':'
    :    # load another copy of the ':' function into memory...
    |    # ...and pipe its output to...
    :    # ...another copy of ':' function, which has to be loaded into memory
         # (therefore, ':|:' simply gets two copies of ':' loaded whenever ':' is called)
    &    # disown the functions -- if the first ':' is killed,
         #     all of the functions that it has started should NOT be auto-killed
}        # end of what to do when we say ':'
;        # Having defined ':', we should now...
:        # ...call ':', initiating a chain-reaction: each ':' will start two more.

7

Зломаний:

: () // Define ':' as a function. When you type ':' do the following
{
    : // Call ':' 
    | // Redirect output
    : // Into ':'
    & // Push process to the background
}; // End of ':' def
: // Now do ':'

Зміна :до bombі у вас є:

bomb(){ bomb|bomb& };bomb

Це дійсно досить елегантно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.