Re: lug-bg: Задачка Закачка: Bash
- Subject: Re: lug-bg: Задачка Закачка: Bash
- From: Peter Pentchev <roam@xxxxxxxxxxx>
- Date: Mon, 29 Nov 2004 15:11:30 +0200
On Mon, Nov 29, 2004 at 02:48:44PM +0200, Andrei Boyanov wrote:
>
>
> Danail Petrov wrote:
>
> >Здравейте ,
> >Преди да напиша каквото и да е ще кажа само: не стартирайте това в
> >нормална конзола, ползвайте ulimit ако сте любопитни.
> >Та ... Какво според Вас прави това в баш шел:
> >
> >
> >:(){ :|:&};:
>
> Прав ли съм като си мисля, че това дефинира функция, която се казва ' :'
> , след което я вика? Тази функция от своя страна се вика сама себе си и
> се праща в бекграунд. И така до безкрай ?
Мда :)
Нещата, които научих от тази история навремето, и които се отнасят не
само за Bash, ами за всякакви Bourne-like shells, включително и това,
което се нарича ash май, и е най-малкият общ знаменател, бяха:
1. ':' е напълно валиден символ за име на функция - спокойно можеш да си
дефинираш функция с име 'furrfu:furrblah' примерно, да си я викаш, и тя
ще си работи. Не знам защо е направено това, знам обаче, че работи :)
2. Bourne shell е силно чувствителен към синтаксис при дефиниция на
функция. Както вече забелязахте, интервалът след отварящата скоба '{' е
доста задължителен, а на всичкото отгоре задължително е и последната
команда в тялото на функцията да завършва с разделител - ';' върши
работа, '&' също, но просто furrfu() { echo "baa" } няма да стане.
А иначе за тези, които още не са вникнали съвсем в странния синтаксис -
това е еквивалентно на следния псевдокод:
1. Дефинирай функция с име ':', която прави следното:
а) извиква функция с име ':' (т.е. рекурсивно извиква себе си)
б) пренасочва изхода й към входа на друга функция с име ':' (т.е.
извиква рекурсивно себе си втори път)
в) слага целия този pipe във фонов режим, така че шелът да не дочака
края на изпълнението на последната команда, ами да си продължи
нататък.
2. Изпълни функцията с име ':'
Това, което се случва след това, е, че всяко изпълнение на ':'
предизвиква още *две* изпълнения на ':', като никое от тях не изчаква
предишното да свърши, ами си генерира нови две и т.н. Разбира се, след
като някоя от ':' е генерирала две нови и е настроила pipe между тях,
нейното изпълнение свършва, но междувременно са се появили две нови, и
така до края на... не, не света, по-скоро търпението на системния
администратор :)
А, забравих май да спомена, че поради спецификата на Bourne shells всяка
от командите, изпълнени в pipe във фонов режим, се изпълнява *в собствен
шел*, т.е. пуска нов процес. По този начин се получава, както стана
ясно, една хубава fork-бомбичка :)
И както се казва, kids, don't try this at home... и в този момент си
припомних реакцията на един бивш шеф от едно бивше работно място, който
при тръгването си от един купон, като забеляза какви креативни начини за
забиване на database server обсъждаме, си тръгна с думите 'Пенчев, don't
try this at home'... и пет секунди след това отвори вратата с крак,
влетя вътре и каза 'ааааааа, и don't try this at work!'
Поздрави,
Петър
--
Peter Pentchev roam@xxxxxxxxxxx roam@xxxxxxxx roam@xxxxxxxxxxx
PGP key: http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint FDBA FD79 C26F 3C51 C95E DF9E ED18 B68D 1619 4553
If this sentence didn't exist, somebody would have invented it.
Attachment:
pgpAcI0tegEJ5.pgp
Description: PGP signature
|