<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://wiki2.linuxformat.ru/skins/common/feed.css?97"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>LXF136:Bash - История изменений</title>
		<link>http://wiki2.linuxformat.ru/index.php?title=LXF136:Bash&amp;action=history</link>
		<description>История изменений этой страницы в вики</description>
		<language>ru</language>
		<generator>MediaWiki 1.11.1</generator>
		<lastBuildDate>Wed, 13 May 2026 20:59:44 GMT</lastBuildDate>
		<item>
			<title>Crazy Rebel: викификация, оформление, иллюстрация</title>
			<link>http://wiki2.linuxformat.ru/index.php?title=LXF136:Bash&amp;diff=12981&amp;oldid=prev</link>
			<description>&lt;p&gt;викификация, оформление, иллюстрация&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая статья&lt;/b&gt;&lt;/p&gt;&lt;div&gt;: '''''Bash''''' Из­вер­ни­тесь в Linux, сэ­ко­но­мив вре­мя и уп­ро­стив се­бе жизнь [[Категория:Учебники]]&lt;br /&gt;
&lt;br /&gt;
==''Bash'': Осваиваем init-файлы==&lt;br /&gt;
&lt;br /&gt;
{{Цикл/Bash}}&lt;br /&gt;
: Соз­дай­те се­бе скрипт '''init.d''' и про­цес­сы-де­мо­ны для сле­же­ния за дос­туп­но­стью се­ти. '''Ник Вейч''' про­ве­дет вас по ка­та­ком­бам ''sysvinit''.&lt;br /&gt;
&lt;br /&gt;
На дан­ном уро­ке мы соз­да­дим скрипт инициа­ли­за­ции. А вы-то ду­ма­ли, это учебник по ''Bash''? Ну, это са­мо со­бой. Скрип­ты инициа­ли­за­ции систе­мы для всех вер­сий и ва­ри­ан­тов Linux (ну, поч­ти для всех) пи­шут­ся для систем­ной обо­лоч­ки, а в боль­шин­стве ди­ст­ри­бу­ти­вов она и есть ''Bash''. Так что напи­сание скрип­тов инициа­ли­за­ции – это про­грам­ми­ро­вание в ''Bash''.&lt;br /&gt;
&lt;br /&gt;
Вся ва­ша ОС Linux по­строе­на во­круг ''Bash'', и это наи­бо­лее оче­видно при взгля­де в ка­та­лог '''/etc'''. Для бо­лее слож­ных про­це­дур неко­то­рые ди­ст­ри­бу­ти­вы при­ме­ня­ют ''Python'', но по­сле­до­ва­тель­ность за­груз­ки все рав­но ра­бо­та­ет в ''Bash'', и все служ­бы и при­ло­жения за­пуска­ют­ся ею че­рез скрипт инициа­ли­за­ции.&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF136_80_1.jpg|300px]] Скрипты ини­циа­ли­за­ции ва­ше­го ди­ст­ри­бу­ти­ва — хороший пример то­го, что мож­но де­лать, хо­тя по боль­шей час­ти они весь­ма слож­ны.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Вы мо­же­те взять лю­бой скрипт ''Bash'', по­местить его в '''/etc/init.d''' и за­ста­вить за­пускать­ся при за­груз­ке. Од­на­ко для стар­то­вых скрип­тов при­нят минималь­ный стан­дарт. Они обя­за­ны принимать па­ра­метр, опи­сы­ваю­щий вы­пол­няе­мое дей­ствие. На са­мом ба­зо­вом уровне это коман­ды '''start, stop''' и '''status'''. В дан­ном учебнике мы еще не стал­ки­ва­лись со вво­дом, так что да­вай­те изу­чим его сей­час. Соз­дай­те сле­дую­щий скрипт и со­храните его под именем '''script1.sh''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 echo You gave me the parameter $1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Те­перь смот­ри­те, что про­изой­дет при его за­пус­ке:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt; sh script2.sh&lt;br /&gt;
 You gave me the parameter&lt;br /&gt;
 &amp;gt; sh script2.sh plop&lt;br /&gt;
 You gave me the parameter plop&lt;br /&gt;
 &amp;gt; sh script2.sh plop plopster&lt;br /&gt;
 You gave me the parameter plop&lt;br /&gt;
&lt;br /&gt;
Пе­ре­мен­ная '''$1''' со­дер­жит пер­вый па­ра­метр, пе­ре­да­вае­мый скрип­ту при его за­пуске. Из при­ме­ров вид­но, что раз­де­ли­те­лем па­ра­мет­ров слу­жит про­бел. Вто­рой па­ра­метр был бы '''$2''', тре­тий – '''$3''', и так да­лее.&lt;br /&gt;
&lt;br /&gt;
===В дан­ном слу­чае===&lt;br /&gt;
&lt;br /&gt;
Те­перь зай­мем­ся об­ра­бот­кой вве­ден­но­го. Как и боль­шин­ство скрип­то­вых язы­ков (исклю­чение – ''Python''), ''Bash'' со­дер­жит кон­ст­рук­цию вы­бо­ра ['''case'''], по­зво­ляю­щую вы­пол­нять оп­ре­де­лен­ные куски ко­да в за­ви­си­мо­сти от зна­чения некой пе­ре­мен­ной. Имен­но это и нуж­но для оп­ре­де­ления це­ли за­пуска скрип­та, и ес­ли вы про­смот­ри­те скрип­ты инициа­ли­за­ции ва­шей систе­мы, то уви­ди­те, что они все ис­поль­зу­ют эту струк­ту­ру.&lt;br /&gt;
&lt;br /&gt;
Итак, все, что необ­хо­ди­мо сде­лать – это соз­дать струк­ту­ру и опи­сать все воз­мож­ные ис­хо­ды:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 case “$1” in&lt;br /&gt;
 	 start)&lt;br /&gt;
 		 echo $”I would if I knew how”&lt;br /&gt;
 		 ;;&lt;br /&gt;
 	 stop)&lt;br /&gt;
 		 echo $”Yes, stopped”&lt;br /&gt;
 		 ;;&lt;br /&gt;
 	 status)&lt;br /&gt;
 		 echo $”Not sure”&lt;br /&gt;
 		 ;;&lt;br /&gt;
 	 *)&lt;br /&gt;
 		 echo $”Usage: $0 {start|stop|status}”&lt;br /&gt;
 esac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Струк­ту­ра очень про­ста, хо­тя и ослож­ня­ет­ся склон­но­стью ''Bash'' к эк­зо­ти­че­ской сим­во­ли­ке. По­сле клю­че­во­го сло­ва '''case''' сле­ду­ет пе­ре­мен­ная-пе­ре­клю­ча­тель, а за­тем '''in'''. Ка­ж­дое рас­смат­ри­вае­мое зна­чение за­вер­ша­ет­ся за­кры­ваю­щей скоб­кой, что­бы от­де­лить его от вы­пол­няе­мо­го ко­да. За­тем эти бло­ки ко­да за­вер­ша­ют­ся сдво­ен­ным сим­во­лом точ­ки с за­пя­той.&lt;br /&gt;
&lt;br /&gt;
В дан­ном при­ме­ре, зна­чение '''*)''' – это остав­шие­ся ва­ри­ан­ты, т. е. «все то, что не пе­ре­чис­ле­но», и в дан­ном слу­чае это оз­на­ча­ет вы­вод справ­ки по ис­поль­зо­ванию.&lt;br /&gt;
&lt;br /&gt;
Из ко­да вид­но, что мы со­сла­лись на '''$0''' – это са­ма вы­зван­ная коман­да. Опе­ра­тор вы­бо­ра за­мы­ка­ет­ся, как и боль­шин­ство кон­ст­рук­ций ''Bash'' (кро­ме '''do'''), клю­че­вым сло­вом, запи­сан­ным на­обо­рот.&lt;br /&gt;
&lt;br /&gt;
Же­лая соз­дать про­стей­ший скрипт, мы мог­ли бы про­сто раз­местить вы­зов тре­буе­мой коман­ды в сек­ции '''start''' ко­да. Но для скрип­та инициа­ли­за­ции это не со­всем хо­ро­шо – сле­ду­ет по­ду­мать о спо­со­бах его ис­поль­зо­вания. Вдруг он бу­дет за­пу­щен два­ж­ды? Все очень за­пу­та­лось бы. И как уз­нать, ко­то­рый про­цесс оста­но­вить? Эх, нам бы спо­соб по­про­ще...&lt;br /&gt;
&lt;br /&gt;
По­сто­ян­ные чи­та­те­ли зна­ют, что та­кие мои сло­ва обыч­но оз­на­ча­ют на­ли­чие неких уло­вок, по­мо­гаю­щих от­вер­теть­ся от тру­дов, и этот раз – не исклю­чение. Исклю­чение – то, что это не трюк; мы восполь­зу­ем­ся ин­ст­ру­мен­та­ми, ко­то­рые и пред­по­ла­га­ет­ся поль­зо­вать­ся!&lt;br /&gt;
&lt;br /&gt;
В ва­шей систе­ме спря­тан неболь­шой скрипт, вы­пол­няю­щий все основ­ные за­да­чи, необ­хо­ди­мые скрип­там инициа­ли­за­ции. Во­об­ще-то в ка­ж­дом ди­ст­ри­бу­ти­ве он свой, и это несколь­ко ослож­ня­ет де­ло. К сча­стью, уси­лия за­ме­ча­тель­ных лю­дей по соз­данию Linux Standard Base [LSB, Ба­зы стан­дар­тов Linux] не про­па­ли зря, и име­ет­ся стан­дар­ти­зо­ван­ная вер­сия это­го скрип­та – ее мож­но най­ти в '''/lib/lsb/init-functions'''. Вы не обя­за­ны ис­поль­зо­вать ее – в Fedora я пред­по­чи­таю стан­дарт­ный скрипт '''functions''' из ка­та­ло­га '''init.d''', но в це­лях соз­дания скрип­та, ра­бо­то­спо­соб­но­го в лю­бом ди­ст­ри­бу­ти­ве, я дол­жен счи­тать­ся с LSB.&lt;br /&gt;
&lt;br /&gt;
Эту тру­до­сбе­ре­гаю­щую часть про­ек­та ''Bash'' нет ну­ж­ды да­же встав­лять в ваш соб­ствен­ный скрипт. ''Bash'' име­ет сред­ства вклю­чения дру­гих скрип­тов при по­мо­щи клю­че­во­го сло­ва '''source''' или '''.'''. Все, что на­до сде­лать – это до­ба­вить сле­дую­щую стро­ку в на­ча­ло со­от­вет­ст­вую­ще­го ко­да:&lt;br /&gt;
&lt;br /&gt;
 . /lib/lsb/init-functions&lt;br /&gt;
&lt;br /&gt;
Те­перь в стро­ке скрип­та по­сле клю­ча '''start)''' мы мо­жем вы­звать од­ну из вспо­мо­га­тель­ных функ­ций, что­бы что-то за­пус­тить:&lt;br /&gt;
&lt;br /&gt;
 start_daemon /bin/echo “I have started so I’ll finish”&lt;br /&gt;
&lt;br /&gt;
Коман­да '''echo''' – не из тех, что вам хо­те­лось бы сде­лать де­мо­ном, но здесь она взя­та про­сто для при­ме­ра. Гру­бо го­во­ря, здесь мож­но за­пустить что угод­но.&lt;br /&gt;
&lt;br /&gt;
===Шаб­ло­ны ва­ри­ан­тов===&lt;br /&gt;
&lt;br /&gt;
Ес­ли вы же­лае­те по­экс­пе­ри­мен­ти­ро­вать с '''case''', мо­же­те вос­поль­зо­вать­ся шаб­ло­на­ми ['''pattern'''] для опи­са­ния же­лае­мо­го ва­ри­ан­та.&lt;br /&gt;
&lt;br /&gt;
* '''?( pattern1 | pattern2 | ...)''' ни од­но­го или од­но вхо­ж­де­ние лю­бо­го из шаб­ло­нов&lt;br /&gt;
* '''*( pattern1 | pattern2 | ...)''' ноль или бо­лее вхо­ж­де­ний лю­бо­го из шаб­ло­нов&lt;br /&gt;
* '''@( pattern1 | pattern2 | ...)''' в точ­но­сти од­но вхо­ж­де­ние лю­бо­го из шаб­ло­нов&lt;br /&gt;
* '''+( pattern1 | pattern2 | ...)''' од­но или бо­лее вхо­ж­де­ний лю­бо­го из шаб­ло­нов&lt;br /&gt;
&lt;br /&gt;
===Что же за­пускать?===&lt;br /&gt;
&lt;br /&gt;
Ок­ру­жение инициа­ли­за­ции раз­ра­бо­та­но для за­пуска де­мо­нов – про­цес­сов, ра­бо­таю­щих са­ми по се­бе в фо­но­вом ре­жи­ме. Я пред­по­ла­гал соз­дать скрипт для че­го-нибудь вро­де torrent-кли­ен­та без обо­лоч­ки, но, про­бе­жав­шись по Ин­тернету, об­на­ру­жил, что боль­шин­ство из них ее име­ют.&lt;br /&gt;
&lt;br /&gt;
Од­на­ко в учеб­ных це­лях и для тести­ро­вания ми­ло бы­ло бы за­пустить служ­бу соб­ствен­но­го изо­бре­тения – в дан­ном слу­чае, дру­гой скрипт ''Bash''. &lt;br /&gt;
&lt;br /&gt;
Вот про­стой скрипт, принимаю­щий две ве­щи: IP-ад­рес и файл жур­на­ла. Уга­дае­те ли вы, что он де­ла­ет?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 #!/bin/bash&lt;br /&gt;
 ADDRESS=$1&lt;br /&gt;
 LOGFILE=$2&lt;br /&gt;
 while true&lt;br /&gt;
 do&lt;br /&gt;
  if /bin/ping -c 2 $ADDRESS &amp;gt; /dev/null&lt;br /&gt;
  then&lt;br /&gt;
 	 echo `date` $ADDRESS online &amp;gt;&amp;gt; $LOGFILE&lt;br /&gt;
  else&lt;br /&gt;
 	 echo `date` $ADDRESS offline &amp;gt;&amp;gt; $LOGFILE&lt;br /&gt;
  fi&lt;br /&gt;
  sleep 60&lt;br /&gt;
 done&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Смысл цик­ла оче­ви­ден, а кон­ст­рук­ция '''if''' мо­жет вас оза­да­чить. Вы помните: то, что сто­ит по­сле '''if''', долж­но быть '''true''' или '''false'''. В дан­ном слу­чае это дей­ствую­щая коман­да. Как же она может быть исти­ной или ло­жью?&lt;br /&gt;
&lt;br /&gt;
Ха-ха, а она воз­вра­ща­ет зна­чение! Коман­да ''ping'' воз­вра­ща­ет '''true''' при успеш­ном за­вер­шении (от­вет по­лу­чен) и '''false''' в про­тив­ном слу­чае.&lt;br /&gt;
&lt;br /&gt;
Итак, в за­ви­си­мо­сти от ре­зуль­та­та, скрипт вы­пол­ня­ет ту или иную коман­ду '''echo'''. В про­шлый раз мы лишь слег­ка косну­лись ис­поль­зо­вания об­рат­но­го штри­ха '''`''' (рас­по­ло­жен обыч­но сле­ва от кла­ви­ши '''1''') в скрип­тах ''Bash''. В та­кие ка­выч­ки за­клю­ча­ют­ся коман­ды, ко­то­рые долж­ны вы­пол­нять­ся «на месте», с под­ста­нов­кой вы­во­да об­рат­но в скрипт. В дан­ном слу­чае мы по­лу­ча­ем вре­мя. Ре­зуль­тат дей­ствия этих строк в том, что вре­мя, ад­рес и ста­тус со­единения до­бав­ля­ет­ся в ука­зан­ный файл жур­на­ла. Коман­да ''sleep'' за­став­ля­ет скрипт ждать 60 се­кунд до сле­дую­щей по­пыт­ки.&lt;br /&gt;
&lt;br /&gt;
В неко­то­рых об­стоя­тель­ствах этот скрипт бы­ва­ет весь­ма по­ле­зен. Его мож­но ис­поль­зо­вать в ка­че­стве про­сто­го монито­ра сер­ве­ра, или для про­вер­ки доступ­но­сти се­те­во­го со­единения. &lt;br /&gt;
&lt;br /&gt;
По­про­буй­те за­пустить его са­мо­стоя­тель­но в команд­ной стро­ке, ука­зав ка­кие-нибудь зна­чения. Скрипт нескон­чае­мый, и для его оста­нов­ки по­тре­бу­ет­ся на­жать '''Ctrl+C'''.&lt;br /&gt;
&lt;br /&gt;
===За­пуска­ем свою служ­бу===&lt;br /&gt;
&lt;br /&gt;
Те­перь мы мо­жем про­сто за­пустить наш скрипт пря­мо из скрип­та инициа­ли­за­ции, но необ­хо­ди­мо не до­пустить по­втор­но­го за­пуска, а так­же знать, как его оста­но­вить. Как это сде­лать? Древние муд­ре­цы Unix, дол­го-дол­го рас­пи­вая ко­фе и ог­ла­жи­вая бо­ро­ды, при­шли к мыс­ли о pid-фай­ле. При ка­ж­дом за­пуске про­цес­су при­сваи­ва­ет­ся но­мер. Про­верь­те это, вве­дя коман­ду ''ps'':&lt;br /&gt;
&lt;br /&gt;
 &amp;gt; ps&lt;br /&gt;
 PID	 TTY	 TIME		 CMD&lt;br /&gt;
 8341	 pts/1	 00:00:00	 su&lt;br /&gt;
 8353	 pts/1	 00:00:00	 bash&lt;br /&gt;
 19369	 pts/1	 00:00:00	 ps&lt;br /&gt;
&lt;br /&gt;
Чис­ло в пер­вом столб­це – уникаль­ный ID про­цес­са, ко­то­рый, сре­ди про­че­го, мож­но ис­поль­зо­вать для сле­жения за про­цес­сом, по­сыл­ки ему сиг­на­лов и его оста­нов­ки.&lt;br /&gt;
&lt;br /&gt;
Pid-файл – про­сто файл, со­дер­жа­щий этот но­мер (или, по­тен­ци­аль­но, несколь­ко но­ме­ров), а так­же удоб­ный спо­соб уз­нать, за­пу­щен ли кон­крет­ный про­цесс, и ес­ли да, то где он. По со­гла­шению, pid-файл хранит­ся в '''/var/run/&amp;lt;имя&amp;gt;.pid.'''&lt;br /&gt;
&lt;br /&gt;
Соз­дание pid-фай­ла – де­ло непро­стое, но нам по­мо­жет систе­ма. В Debian и его про­из­вод­ных (это про вас, убун­тои­ды) име­ет­ся ис­пол­няе­мый файл по имени ''start-stop-daemon'', и мы им восполь­зу­ем­ся. В Fedora мож­но под­клю­чить скрипт '''/etc/init.d/functions''' и ис­поль­зо­вать вме­сто это­го ''daemon''. Кро­ме то­го, для соз­дания pid-фай­ла сго­дит­ся и сам скрипт. ''Bash'' уз­на­ет но­мер сво­его соб­ствен­но­го про­цес­са из внут­ренней пе­ре­мен­ной '''$$''', так что мож­но про­сто вы­полнить коман­ду&lt;br /&gt;
&lt;br /&gt;
 echo $$ &amp;gt; /var/run/netcheckd.pid&lt;br /&gt;
&lt;br /&gt;
При за­пуске пря­мо из скрип­та она соз­даст же­лае­мый pid-файл. Но да­лее мы бу­дем дер­жать­ся спо­со­ба Debian/Ubuntu.&lt;br /&gt;
&lt;br /&gt;
Восполь­зо­вав­шись ''start-stop-daemon'', мы мо­жем соз­да­вать pid-файл сра­зу по­сле за­пуска на­ше­го скрип­та. Нуж­но так­же пе­ре­дать ему несколь­ко па­ра­мет­ров, что­бы со­об­щить, ка­кую опе­ра­цию сле­ду­ет вы­полнить:&lt;br /&gt;
&lt;br /&gt;
 start-stop-daemon --start -b --pidfile /var/run/netcheckd.pid --make-pidfile &lt;br /&gt;
 --exec /usr/sbin/netcheck 192.168.0.1 /home/evilnick/netcheck.log&lt;br /&gt;
&lt;br /&gt;
Ключ '''--start''' со­об­ща­ет за­груз­чи­ку, ка­кую про­грам­му мы хо­тим за­пустить. Ключ '''--pidfile''' оп­ре­де­ля­ет рас­по­ло­жение pid-фай­ла. До­бав­ление '''--make-pidfile''' при­во­дит к соз­данию это­го фай­ла (c PID внут­ри), ес­ли он не су­ще­ству­ет, а да­лее по­сле '''--exec''' идет коман­да, ко­то­рую мы хо­тим вы­полнить.&lt;br /&gt;
&lt;br /&gt;
Ключ '''-b''' нам на­до ис­поль­зо­вать, по­сколь­ку мы за­пуска­ем дру­гой скрипт. Обыч­но дво­ич­ная коман­да раз­ветв­ля­ет свой про­цесс так, что­бы ра­бо­тать в фоне. Скрип­ты ''Bash'' это­го не де­ла­ют, и ес­ли мы не за­пустим наш скрипт в фо­но­вом ре­жи­ме, init-скрипт никогда не за­вер­шит­ся. Это не здо­ро­во, по­сколь­ку оз­на­ча­ет, что на­до до­ба­вить соб­ствен­ные про­вер­ки для сле­жения за про­цес­сом, но не так уж труд­но.&lt;br /&gt;
&lt;br /&gt;
Итак, те­перь мы мо­жем из­менить на­чаль­ный раз­дел сле­дую­щим об­ра­зом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 start)&lt;br /&gt;
 	 if [ -f $PIDFILE ]; then&lt;br /&gt;
 	 log_failure_msg “Process running already”&lt;br /&gt;
 	 exit 1&lt;br /&gt;
 	 fi&lt;br /&gt;
 	 start-stop-daemon --start -b \&lt;br /&gt;
 		--pidfile $PIDFILE --make-pidfile \&lt;br /&gt;
 		--exec $NAME $ADDRESS $LOGFILE&lt;br /&gt;
 	 ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В на­чаль­ном раз­де­ле ко­да про­ве­ря­ет­ся су­ще­ство­вание pid-фай­ла, и ес­ли он есть, то пе­ред за­вер­шением вы­да­ет­ся со­об­щение об ошиб­ке. Ес­ли файл не су­ще­ству­ет, мы мо­жем за­пустить наш де­мон.&lt;br /&gt;
&lt;br /&gt;
Вы мо­же­те за­ме­тить, что все со­пут­ствую­щие де­та­ли за­менены пе­ре­мен­ны­ми. Мы хо­тим ак­ку­рат­но об­ра­щать­ся со зна­чения­ми и лег­ко на­хо­дить их, по­это­му вы­де­лим их и раз­местим в на­ча­ле фай­ла.&lt;br /&gt;
&lt;br /&gt;
Вклю­чение LSB – боль­шое де­ло для ди­ст­ри­бу­ти­вов, но они так­же долж­ны со­от­вет­ство­вать неко­то­рым стан­дар­там, один из ко­то­рых – боль­шой блок-ком­мен­та­рий в на­ча­ле скрип­тов инициа­ли­за­ции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 ### BEGIN INIT INFO&lt;br /&gt;
 # Provides: netcheckd&lt;br /&gt;
 # Required-Start: $local_fs $remote_fs $network&lt;br /&gt;
 # Required-Stop: $local_fs $remote_fs $network&lt;br /&gt;
 # Default-Start: 2 3 4 5&lt;br /&gt;
 # Default-Stop: 0 1 6&lt;br /&gt;
 # Short-Description: manage the network check script&lt;br /&gt;
 ### END INIT INFO&lt;br /&gt;
 NAME=netcheck&lt;br /&gt;
 SCRIPT=/usr/bin/$NAME&lt;br /&gt;
 PIDFILE=/var/run/$NAME.pid&lt;br /&gt;
 ADDRESS=192.168.0.1&lt;br /&gt;
 LOGFILE=/var/log/${NAME}.log&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конеч­но же, вы мо­же­те из­менить эти зна­чения на под­хо­дя­щие вам. По­сколь­ку по умол­чанию скрипт за­пуска­ет­ся от имени root, он име­ет доступ к ка­та­ло­гу '''/var''' для соз­дания pid-фай­ла и жур­на­ла. Вы мо­же­те по­же­лать за­пустить де­мон от имени дру­го­го поль­зо­ва­те­ля – и это воз­мож­но, но тогда файл жур­на­ла сле­ду­ет хранить где-то в дру­гом месте.&lt;br /&gt;
&lt;br /&gt;
===Оста­но­ви­те его===&lt;br /&gt;
&lt;br /&gt;
Итак, мы за­пусти­ли на­шу коман­ду – а как ее оста­но­вить? Pid-файл пре­достав­ля­ет нам но­мер про­цес­са ра­бо­таю­ще­го скрип­та, а зная но­мер, мож­но про­сто унич­то­жить про­цесс коман­дой ''kill''. За­тем не за­будь­те очи­стить и уда­лить pid-файл, что­бы де­мон мож­но бы­ло за­пустить вновь:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 stop)&lt;br /&gt;
 	 if [ -f $PIDFILE ]; then&lt;br /&gt;
 	 PID=`cat $PIDFILE`&lt;br /&gt;
 	 #про­ве­ря­ем за­пу­щен ли про­цесс&lt;br /&gt;
 	 if `ps $PID &amp;gt;/dev/null` ; then&lt;br /&gt;
 	 kill -HUP $PID&lt;br /&gt;
 	 log_success_msg “Process stopped”&lt;br /&gt;
 	 else&lt;br /&gt;
 	 log_failure_msg “Process not running”&lt;br /&gt;
 	 fi&lt;br /&gt;
 	 # уда­ля­ем Pid-файлв лю­бом слу­чае&lt;br /&gt;
 	 rm $PIDFILE&lt;br /&gt;
 	 else&lt;br /&gt;
 	 log_failure_msg “Process not running”&lt;br /&gt;
 	 fi&lt;br /&gt;
 	 ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Здесь мы про­ве­ря­ем, что pid-файл су­ще­ству­ет, ина­че счи­та­ем, что про­цесс не за­пу­щен. За­тем из­вле­ка­ем ID про­цес­са при по­мо­щи ма­гии об­рат­но­го апо­ст­ро­фа и про­ве­ря­ем коман­дой ''ps'', что он дей­стви­тель­но су­ще­ству­ет. Ес­ли су­ще­ству­ет, то унич­то­жа­ем [''kill''] его.&lt;br /&gt;
&lt;br /&gt;
При­менение коман­ды ''kill'' – это су­ро­во. Мож­но восполь­зо­вать­ся сиг­на­лом SIGHUP: он веж­ли­во по­про­сит про­цесс уме­реть. Для на­ше­го скрип­та это­го бу­дет доста­точ­но (он от­ра­бо­та­ет оста­ток вы­пол­няю­щей­ся коман­ды ''sleep'' и за­кро­ет­ся).&lt;br /&gt;
&lt;br /&gt;
Кро­ме то­го, пе­ред вы­хо­дом сле­ду­ет уда­лить pid-файл. Это не са­мый на­деж­ный скрипт – сле­до­ва­ло бы про­ве­рить, сра­бо­та­ла ли коман­да ''kill'', а уж по­том тру­бить сиг­нал об успеш­ном вы­полнении. Это оз­на­ча­ет ожи­дание и до­полнитель­ную про­вер­ку спи­ска про­цес­сов, а до­ба­влять ее или нет – ре­шать вам.&lt;br /&gt;
&lt;br /&gt;
Мы так­же долж­ны до­ба­вить ука­за­тель ста­ту­са. Это сво­дит­ся лишь к неболь­шой пе­ре­ра­бот­ке бло­ка '''stop''':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=bash&amp;gt;&lt;br /&gt;
 status)&lt;br /&gt;
 	 if [ -f $PIDFILE ]; then&lt;br /&gt;
 	 PID=`cat $PIDFILE`&lt;br /&gt;
 	 #про­ве­ря­ем, за­пу­щен ли про­цесс&lt;br /&gt;
 	 if `ps $PID &amp;gt;/dev/null` ; then&lt;br /&gt;
 	 log_success_msg “Process running”&lt;br /&gt;
 	 else&lt;br /&gt;
 	 log_warn_msg “Process has failed... removing pidfile”&lt;br /&gt;
 	 rm $PIDFILE&lt;br /&gt;
 	 fi&lt;br /&gt;
 	 else&lt;br /&gt;
 	 log_success_msg “Process not running”&lt;br /&gt;
 	 fi&lt;br /&gt;
 	 ;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тут мы до­ба­ви­ли про­вер­ку кор­рект­но­сти pid-фай­ла. Ес­ли все вы­гля­дит так, буд­то про­цесс за­пу­щен, но он не об­на­ру­жи­ва­ет­ся, мы про­сто уда­ля­ем уста­рев­ший pid-файл. Та­кое бы­ва­ет в слу­чае некор­рект­но­го вы­клю­чения ма­ши­ны или ес­ли ка­кая-то коман­да уби­ла наш скрипт.&lt;br /&gt;
&lt;br /&gt;
Дру­гая часто реа­ли­зуе­мая оп­ция в та­ких скрип­тах – '''restart''' [пе­ре­за­груз­ка]. В про­стей­шем слу­чае это опе­ра­ция '''stop''', за ко­то­рой сле­ду­ет опе­ра­ция '''start''', и вы мо­же­те лег­ко вы­де­лить ка­ж­дое дей­ствие в функ­цию, а за­тем про­сто объ­е­динить их вме­сте в '''restart'''.&lt;br /&gt;
&lt;br /&gt;
Вы най­де­те пол­ную вер­сию скрип­та сле­жения за се­тью на на­шем сай­те http://www.linuxformat.com/files/136bash.zip.&lt;br /&gt;
&lt;br /&gt;
Ес­ли за­пустить пол­ный скрипт локаль­но, вы долж­ны уви­деть&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;sh netcheckd status&lt;br /&gt;
 * Process not running&lt;br /&gt;
 &amp;gt; sh netcheckd start&lt;br /&gt;
 * netcheck started&lt;br /&gt;
 &amp;gt; sh netcheckd status&lt;br /&gt;
 * Process running&lt;br /&gt;
 &amp;gt; sh netcheckd stop&lt;br /&gt;
 * Process stopped&lt;br /&gt;
 &amp;gt; netcheckd restart&lt;br /&gt;
 * Process not running&lt;br /&gt;
 * netcheck started&lt;br /&gt;
 &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оста­лось по­местить фай­лы в долж­ные ка­та­ло­ги ('''/etc/init.d/netcheckd''', '''/usr/bin/netcheck''') и, ес­ли по­же­лае­те, до­ба­вить их в спи­сок ав­то­за­пуска. В Ubuntu для это­го про­сто вы­полните:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;sudo update-rc.d netcheckd defaults&lt;br /&gt;
 Adding system startup for /etc/init.d/netcheckd ...&lt;br /&gt;
 /etc/rc0.d/K20netcheckd -&amp;gt; ../init.d/netcheckd&lt;br /&gt;
 /etc/rc1.d/K20netcheckd -&amp;gt; ../init.d/netcheckd&lt;br /&gt;
 /etc/rc6.d/K20netcheckd -&amp;gt; ../init.d/netcheckd&lt;br /&gt;
 /etc/rc2.d/S20netcheckd -&amp;gt; ../init.d/netcheckd&lt;br /&gt;
 /etc/rc3.d/S20netcheckd -&amp;gt; ../init.d/netcheckd&lt;br /&gt;
 /etc/rc4.d/S20netcheckd -&amp;gt; ../init.d/netcheckd&lt;br /&gt;
 /etc/rc5.d/S20netcheckd -&amp;gt; ../init.d/netcheckd&lt;br /&gt;
 &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Точ­ный ме­ха­низм варь­и­ру­ет­ся. В Fedora и Red Hat для то­го же ис­поль­зу­ет­ся ''chkconfig''.&lt;br /&gt;
&lt;br /&gt;
Да, и по­след­нее... ес­ли вы за­хо­ти­те по­экс­пе­ри­мен­ти­ро­вать, де­лай­те все на тес­то­вой или вир­ту­аль­ной ма­ши­не – в кон­це кон­цов, мы же не хо­тим вы­вес­ти из строя ос­нов­ной Linux-ком­пь­ю­тер!&lt;br /&gt;
&lt;br /&gt;
===Фай­ло­вые про­вер­ки===&lt;br /&gt;
&lt;br /&gt;
Фай­ло­вые про­вер­ки очень час­то ис­поль­зу­ют­ся при соз­да­нии скрип­тов в ''Bash'', и сто­ит за­пом­нить эти, воз­вра­щаю­щие зна­че­ние '''true''' или '''false''' для кон­ст­рук­ции '''if'''. Ес­ли вам такое не по си­лам, за­пом­ни­те хо­тя бы, где на­хо­дит­ся данный спи­сок!&lt;br /&gt;
* '''-b filename''' 		Спе­ци­аль­ный файл блоч­но­го уст­рой­ст­ва.&lt;br /&gt;
* '''-c filename''' 		Спе­ци­аль­ный файл сим­воль­но­го уст­рой­ст­ва.&lt;br /&gt;
* '''-d directoryname''' 	Про­вер­ка су­ще­ст­во­ва­ния ка­та­ло­га.&lt;br /&gt;
* '''-e filename''' 		Про­вер­ка су­ще­ст­во­ва­ния фай­ла.&lt;br /&gt;
* '''-f filename''' 		Про­вер­ка су­ще­ст­во­ва­ния обыч­но­го фай­ла, не ка­та­ло­га.&lt;br /&gt;
* '''-G filename''' 		Про­вер­ка су­ще­ст­во­ва­ния фай­ла и при­над­леж­но­сти груп­пе с те­ку­щим эф­фек­тив­ным ID.&lt;br /&gt;
* '''-g filename''' 		True, ес­ли файл су­ще­ст­ву­ет и ус­та­нов­лен ат­ри­бут set-group-id.&lt;br /&gt;
* '''-k filename''' 		«Лип­кий» бит.&lt;br /&gt;
* '''-L filename''' 		Сим­воль­ная ссыл­ка.&lt;br /&gt;
* '''-O filename''' 		'''True''', ес­ли файл су­ще­ст­ву­ет и при­над­ле­жит поль­зо­ва­те­лю с те­ку­щим эф­фек­тив­ным ID.&lt;br /&gt;
* '''-r filename''' 		Про­вер­ка дос­туп­но­сти фай­ла на чте­ние. &lt;br /&gt;
* '''-S filename''' 		Про­вер­ка, яв­ля­ет­ся ли файл со­ке­том.&lt;br /&gt;
* '''-s filename''' 		Про­вер­ка, что файл име­ет не­ну­ле­вой раз­мер.&lt;br /&gt;
* '''-u filename''' 		Про­вер­ка на­ли­чия би­та '''set-user-id'''.&lt;br /&gt;
* '''-w filename''' 		Про­вер­ка дос­туп­но­сти фай­ла на за­пись.&lt;br /&gt;
* '''-x filename''' 		Яв­ля­ет­ся ли файл ис­пол­няе­мым.&lt;/div&gt;</description>
			<pubDate>Fri, 11 Nov 2011 12:46:10 GMT</pubDate>			<dc:creator>Crazy Rebel</dc:creator>			<comments>http://wiki2.linuxformat.ru/index.php/%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:LXF136:Bash</comments>		</item>
	</channel>
</rss>