LXF136:Bash

Материал из Linuxformat.

Перейти к: навигация, поиск
Bash Из­вер­ни­тесь в Linux, сэ­ко­но­мив вре­мя и уп­ро­стив се­бе жизнь

Содержание

Bash: Осваиваем init-файлы

Bash. Рэйчел Проберт
Bash. Ник Вейч
Соз­дай­те се­бе скрипт init.d и про­цес­сы-де­мо­ны для сле­же­ния за дос­туп­но­стью се­ти. Ник Вейч про­ве­дет вас по ка­та­ком­бам sysvinit.

На дан­ном уро­ке мы соз­да­дим скрипт инициа­ли­за­ции. А вы-то ду­ма­ли, это учебник по Bash? Ну, это са­мо со­бой. Скрип­ты инициа­ли­за­ции систе­мы для всех вер­сий и ва­ри­ан­тов Linux (ну, поч­ти для всех) пи­шут­ся для систем­ной обо­лоч­ки, а в боль­шин­стве ди­ст­ри­бу­ти­вов она и есть Bash. Так что напи­сание скрип­тов инициа­ли­за­ции – это про­грам­ми­ро­вание в Bash.

Вся ва­ша ОС Linux по­строе­на во­круг Bash, и это наи­бо­лее оче­видно при взгля­де в ка­та­лог /etc. Для бо­лее слож­ных про­це­дур неко­то­рые ди­ст­ри­бу­ти­вы при­ме­ня­ют Python, но по­сле­до­ва­тель­ность за­груз­ки все рав­но ра­бо­та­ет в Bash, и все служ­бы и при­ло­жения за­пуска­ют­ся ею че­рез скрипт инициа­ли­за­ции.

Скрипты ини­циа­ли­за­ции ва­ше­го ди­ст­ри­бу­ти­ва — хороший пример то­го, что мож­но де­лать, хо­тя по боль­шей час­ти они весь­ма слож­ны.

Вы мо­же­те взять лю­бой скрипт Bash, по­местить его в /etc/init.d и за­ста­вить за­пускать­ся при за­груз­ке. Од­на­ко для стар­то­вых скрип­тов при­нят минималь­ный стан­дарт. Они обя­за­ны принимать па­ра­метр, опи­сы­ваю­щий вы­пол­няе­мое дей­ствие. На са­мом ба­зо­вом уровне это коман­ды start, stop и status. В дан­ном учебнике мы еще не стал­ки­ва­лись со вво­дом, так что да­вай­те изу­чим его сей­час. Соз­дай­те сле­дую­щий скрипт и со­храните его под именем script1.sh:

#!/bin/bash
 echo You gave me the parameter $1

Те­перь смот­ри­те, что про­изой­дет при его за­пус­ке:

> sh script2.sh
You gave me the parameter
> sh script2.sh plop
You gave me the parameter plop
> sh script2.sh plop plopster
You gave me the parameter plop

Пе­ре­мен­ная $1 со­дер­жит пер­вый па­ра­метр, пе­ре­да­вае­мый скрип­ту при его за­пуске. Из при­ме­ров вид­но, что раз­де­ли­те­лем па­ра­мет­ров слу­жит про­бел. Вто­рой па­ра­метр был бы $2, тре­тий – $3, и так да­лее.

В дан­ном слу­чае

Те­перь зай­мем­ся об­ра­бот­кой вве­ден­но­го. Как и боль­шин­ство скрип­то­вых язы­ков (исклю­чение – Python), Bash со­дер­жит кон­ст­рук­цию вы­бо­ра [case], по­зво­ляю­щую вы­пол­нять оп­ре­де­лен­ные куски ко­да в за­ви­си­мо­сти от зна­чения некой пе­ре­мен­ной. Имен­но это и нуж­но для оп­ре­де­ления це­ли за­пуска скрип­та, и ес­ли вы про­смот­ри­те скрип­ты инициа­ли­за­ции ва­шей систе­мы, то уви­ди­те, что они все ис­поль­зу­ют эту струк­ту­ру.

Итак, все, что необ­хо­ди­мо сде­лать – это соз­дать струк­ту­ру и опи­сать все воз­мож­ные ис­хо­ды:

#!/bin/bash
 case “$1in
 	 start)
 		 echo $”I would if I knew how”
 		 ;;
 	 stop)
 		 echo $”Yes, stopped”
 		 ;;
 	 status)
 		 echo $”Not sure”
 		 ;;
 	 *)
 		 echo $”Usage: $0 {start|stop|status}esac

Струк­ту­ра очень про­ста, хо­тя и ослож­ня­ет­ся склон­но­стью Bash к эк­зо­ти­че­ской сим­во­ли­ке. По­сле клю­че­во­го сло­ва case сле­ду­ет пе­ре­мен­ная-пе­ре­клю­ча­тель, а за­тем in. Ка­ж­дое рас­смат­ри­вае­мое зна­чение за­вер­ша­ет­ся за­кры­ваю­щей скоб­кой, что­бы от­де­лить его от вы­пол­няе­мо­го ко­да. За­тем эти бло­ки ко­да за­вер­ша­ют­ся сдво­ен­ным сим­во­лом точ­ки с за­пя­той.

В дан­ном при­ме­ре, зна­чение *) – это остав­шие­ся ва­ри­ан­ты, т. е. «все то, что не пе­ре­чис­ле­но», и в дан­ном слу­чае это оз­на­ча­ет вы­вод справ­ки по ис­поль­зо­ванию.

Из ко­да вид­но, что мы со­сла­лись на $0 – это са­ма вы­зван­ная коман­да. Опе­ра­тор вы­бо­ра за­мы­ка­ет­ся, как и боль­шин­ство кон­ст­рук­ций Bash (кро­ме do), клю­че­вым сло­вом, запи­сан­ным на­обо­рот.

Же­лая соз­дать про­стей­ший скрипт, мы мог­ли бы про­сто раз­местить вы­зов тре­буе­мой коман­ды в сек­ции start ко­да. Но для скрип­та инициа­ли­за­ции это не со­всем хо­ро­шо – сле­ду­ет по­ду­мать о спо­со­бах его ис­поль­зо­вания. Вдруг он бу­дет за­пу­щен два­ж­ды? Все очень за­пу­та­лось бы. И как уз­нать, ко­то­рый про­цесс оста­но­вить? Эх, нам бы спо­соб по­про­ще...

По­сто­ян­ные чи­та­те­ли зна­ют, что та­кие мои сло­ва обыч­но оз­на­ча­ют на­ли­чие неких уло­вок, по­мо­гаю­щих от­вер­теть­ся от тру­дов, и этот раз – не исклю­чение. Исклю­чение – то, что это не трюк; мы восполь­зу­ем­ся ин­ст­ру­мен­та­ми, ко­то­рые и пред­по­ла­га­ет­ся поль­зо­вать­ся!

В ва­шей систе­ме спря­тан неболь­шой скрипт, вы­пол­няю­щий все основ­ные за­да­чи, необ­хо­ди­мые скрип­там инициа­ли­за­ции. Во­об­ще-то в ка­ж­дом ди­ст­ри­бу­ти­ве он свой, и это несколь­ко ослож­ня­ет де­ло. К сча­стью, уси­лия за­ме­ча­тель­ных лю­дей по соз­данию Linux Standard Base [LSB, Ба­зы стан­дар­тов Linux] не про­па­ли зря, и име­ет­ся стан­дар­ти­зо­ван­ная вер­сия это­го скрип­та – ее мож­но най­ти в /lib/lsb/init-functions. Вы не обя­за­ны ис­поль­зо­вать ее – в Fedora я пред­по­чи­таю стан­дарт­ный скрипт functions из ка­та­ло­га init.d, но в це­лях соз­дания скрип­та, ра­бо­то­спо­соб­но­го в лю­бом ди­ст­ри­бу­ти­ве, я дол­жен счи­тать­ся с LSB.

Эту тру­до­сбе­ре­гаю­щую часть про­ек­та Bash нет ну­ж­ды да­же встав­лять в ваш соб­ствен­ный скрипт. Bash име­ет сред­ства вклю­чения дру­гих скрип­тов при по­мо­щи клю­че­во­го сло­ва source или .. Все, что на­до сде­лать – это до­ба­вить сле­дую­щую стро­ку в на­ча­ло со­от­вет­ст­вую­ще­го ко­да:

. /lib/lsb/init-functions

Те­перь в стро­ке скрип­та по­сле клю­ча start) мы мо­жем вы­звать од­ну из вспо­мо­га­тель­ных функ­ций, что­бы что-то за­пус­тить:

start_daemon /bin/echo “I have started so I’ll finish”

Коман­да echo – не из тех, что вам хо­те­лось бы сде­лать де­мо­ном, но здесь она взя­та про­сто для при­ме­ра. Гру­бо го­во­ря, здесь мож­но за­пустить что угод­но.

Шаб­ло­ны ва­ри­ан­тов

Ес­ли вы же­лае­те по­экс­пе­ри­мен­ти­ро­вать с case, мо­же­те вос­поль­зо­вать­ся шаб­ло­на­ми [pattern] для опи­са­ния же­лае­мо­го ва­ри­ан­та.

  • ?( pattern1 | pattern2 | ...) ни од­но­го или од­но вхо­ж­де­ние лю­бо­го из шаб­ло­нов
  • *( pattern1 | pattern2 | ...) ноль или бо­лее вхо­ж­де­ний лю­бо­го из шаб­ло­нов
  • @( pattern1 | pattern2 | ...) в точ­но­сти од­но вхо­ж­де­ние лю­бо­го из шаб­ло­нов
  • +( pattern1 | pattern2 | ...) од­но или бо­лее вхо­ж­де­ний лю­бо­го из шаб­ло­нов

Что же за­пускать?

Ок­ру­жение инициа­ли­за­ции раз­ра­бо­та­но для за­пуска де­мо­нов – про­цес­сов, ра­бо­таю­щих са­ми по се­бе в фо­но­вом ре­жи­ме. Я пред­по­ла­гал соз­дать скрипт для че­го-нибудь вро­де torrent-кли­ен­та без обо­лоч­ки, но, про­бе­жав­шись по Ин­тернету, об­на­ру­жил, что боль­шин­ство из них ее име­ют.

Од­на­ко в учеб­ных це­лях и для тести­ро­вания ми­ло бы­ло бы за­пустить служ­бу соб­ствен­но­го изо­бре­тения – в дан­ном слу­чае, дру­гой скрипт Bash.

Вот про­стой скрипт, принимаю­щий две ве­щи: IP-ад­рес и файл жур­на­ла. Уга­дае­те ли вы, что он де­ла­ет?

#!/bin/bash
 ADDRESS=$1
 LOGFILE=$2
 while true
 do
  if /bin/ping -c 2 $ADDRESS > /dev/null
  then
 	 echo `date` $ADDRESS online >> $LOGFILE
  else
 	 echo `date` $ADDRESS offline >> $LOGFILE
  fi
  sleep 60
 done

Смысл цик­ла оче­ви­ден, а кон­ст­рук­ция if мо­жет вас оза­да­чить. Вы помните: то, что сто­ит по­сле if, долж­но быть true или false. В дан­ном слу­чае это дей­ствую­щая коман­да. Как же она может быть исти­ной или ло­жью?

Ха-ха, а она воз­вра­ща­ет зна­чение! Коман­да ping воз­вра­ща­ет true при успеш­ном за­вер­шении (от­вет по­лу­чен) и false в про­тив­ном слу­чае.

Итак, в за­ви­си­мо­сти от ре­зуль­та­та, скрипт вы­пол­ня­ет ту или иную коман­ду echo. В про­шлый раз мы лишь слег­ка косну­лись ис­поль­зо­вания об­рат­но­го штри­ха ` (рас­по­ло­жен обыч­но сле­ва от кла­ви­ши 1) в скрип­тах Bash. В та­кие ка­выч­ки за­клю­ча­ют­ся коман­ды, ко­то­рые долж­ны вы­пол­нять­ся «на месте», с под­ста­нов­кой вы­во­да об­рат­но в скрипт. В дан­ном слу­чае мы по­лу­ча­ем вре­мя. Ре­зуль­тат дей­ствия этих строк в том, что вре­мя, ад­рес и ста­тус со­единения до­бав­ля­ет­ся в ука­зан­ный файл жур­на­ла. Коман­да sleep за­став­ля­ет скрипт ждать 60 се­кунд до сле­дую­щей по­пыт­ки.

В неко­то­рых об­стоя­тель­ствах этот скрипт бы­ва­ет весь­ма по­ле­зен. Его мож­но ис­поль­зо­вать в ка­че­стве про­сто­го монито­ра сер­ве­ра, или для про­вер­ки доступ­но­сти се­те­во­го со­единения.

По­про­буй­те за­пустить его са­мо­стоя­тель­но в команд­ной стро­ке, ука­зав ка­кие-нибудь зна­чения. Скрипт нескон­чае­мый, и для его оста­нов­ки по­тре­бу­ет­ся на­жать Ctrl+C.

За­пуска­ем свою служ­бу

Те­перь мы мо­жем про­сто за­пустить наш скрипт пря­мо из скрип­та инициа­ли­за­ции, но необ­хо­ди­мо не до­пустить по­втор­но­го за­пуска, а так­же знать, как его оста­но­вить. Как это сде­лать? Древние муд­ре­цы Unix, дол­го-дол­го рас­пи­вая ко­фе и ог­ла­жи­вая бо­ро­ды, при­шли к мыс­ли о pid-фай­ле. При ка­ж­дом за­пуске про­цес­су при­сваи­ва­ет­ся но­мер. Про­верь­те это, вве­дя коман­ду ps:

> ps
PID	 TTY	 TIME		 CMD
8341	 pts/1	 00:00:00	 su
8353	 pts/1	 00:00:00	 bash
19369	 pts/1	 00:00:00	 ps

Чис­ло в пер­вом столб­це – уникаль­ный ID про­цес­са, ко­то­рый, сре­ди про­че­го, мож­но ис­поль­зо­вать для сле­жения за про­цес­сом, по­сыл­ки ему сиг­на­лов и его оста­нов­ки.

Pid-файл – про­сто файл, со­дер­жа­щий этот но­мер (или, по­тен­ци­аль­но, несколь­ко но­ме­ров), а так­же удоб­ный спо­соб уз­нать, за­пу­щен ли кон­крет­ный про­цесс, и ес­ли да, то где он. По со­гла­шению, pid-файл хранит­ся в /var/run/<имя>.pid.

Соз­дание pid-фай­ла – де­ло непро­стое, но нам по­мо­жет систе­ма. В Debian и его про­из­вод­ных (это про вас, убун­тои­ды) име­ет­ся ис­пол­няе­мый файл по имени start-stop-daemon, и мы им восполь­зу­ем­ся. В Fedora мож­но под­клю­чить скрипт /etc/init.d/functions и ис­поль­зо­вать вме­сто это­го daemon. Кро­ме то­го, для соз­дания pid-фай­ла сго­дит­ся и сам скрипт. Bash уз­на­ет но­мер сво­его соб­ствен­но­го про­цес­са из внут­ренней пе­ре­мен­ной $$, так что мож­но про­сто вы­полнить коман­ду

echo $$ > /var/run/netcheckd.pid

При за­пуске пря­мо из скрип­та она соз­даст же­лае­мый pid-файл. Но да­лее мы бу­дем дер­жать­ся спо­со­ба Debian/Ubuntu.

Восполь­зо­вав­шись start-stop-daemon, мы мо­жем соз­да­вать pid-файл сра­зу по­сле за­пуска на­ше­го скрип­та. Нуж­но так­же пе­ре­дать ему несколь­ко па­ра­мет­ров, что­бы со­об­щить, ка­кую опе­ра­цию сле­ду­ет вы­полнить:

start-stop-daemon --start -b --pidfile /var/run/netcheckd.pid --make-pidfile 
--exec /usr/sbin/netcheck 192.168.0.1 /home/evilnick/netcheck.log

Ключ --start со­об­ща­ет за­груз­чи­ку, ка­кую про­грам­му мы хо­тим за­пустить. Ключ --pidfile оп­ре­де­ля­ет рас­по­ло­жение pid-фай­ла. До­бав­ление --make-pidfile при­во­дит к соз­данию это­го фай­ла (c PID внут­ри), ес­ли он не су­ще­ству­ет, а да­лее по­сле --exec идет коман­да, ко­то­рую мы хо­тим вы­полнить.

Ключ -b нам на­до ис­поль­зо­вать, по­сколь­ку мы за­пуска­ем дру­гой скрипт. Обыч­но дво­ич­ная коман­да раз­ветв­ля­ет свой про­цесс так, что­бы ра­бо­тать в фоне. Скрип­ты Bash это­го не де­ла­ют, и ес­ли мы не за­пустим наш скрипт в фо­но­вом ре­жи­ме, init-скрипт никогда не за­вер­шит­ся. Это не здо­ро­во, по­сколь­ку оз­на­ча­ет, что на­до до­ба­вить соб­ствен­ные про­вер­ки для сле­жения за про­цес­сом, но не так уж труд­но.

Итак, те­перь мы мо­жем из­менить на­чаль­ный раз­дел сле­дую­щим об­ра­зом:

start)
 	 if [ -f $PIDFILE ]; then
 	 log_failure_msg “Process running already”
 	 exit 1
 	 fi
 	 start-stop-daemon --start -b \
 		--pidfile $PIDFILE --make-pidfile \
 		--exec $NAME $ADDRESS $LOGFILE
 	 ;;

В на­чаль­ном раз­де­ле ко­да про­ве­ря­ет­ся су­ще­ство­вание pid-фай­ла, и ес­ли он есть, то пе­ред за­вер­шением вы­да­ет­ся со­об­щение об ошиб­ке. Ес­ли файл не су­ще­ству­ет, мы мо­жем за­пустить наш де­мон.

Вы мо­же­те за­ме­тить, что все со­пут­ствую­щие де­та­ли за­менены пе­ре­мен­ны­ми. Мы хо­тим ак­ку­рат­но об­ра­щать­ся со зна­чения­ми и лег­ко на­хо­дить их, по­это­му вы­де­лим их и раз­местим в на­ча­ле фай­ла.

Вклю­чение LSB – боль­шое де­ло для ди­ст­ри­бу­ти­вов, но они так­же долж­ны со­от­вет­ство­вать неко­то­рым стан­дар­там, один из ко­то­рых – боль­шой блок-ком­мен­та­рий в на­ча­ле скрип­тов инициа­ли­за­ции:

### BEGIN INIT INFO
 # Provides: netcheckd
 # Required-Start: $local_fs $remote_fs $network
 # Required-Stop: $local_fs $remote_fs $network
 # Default-Start: 2 3 4 5
 # Default-Stop: 0 1 6
 # Short-Description: manage the network check script
 ### END INIT INFO
 NAME=netcheck
 SCRIPT=/usr/bin/$NAME
 PIDFILE=/var/run/$NAME.pid
 ADDRESS=192.168.0.1
 LOGFILE=/var/log/${NAME}.log

Конеч­но же, вы мо­же­те из­менить эти зна­чения на под­хо­дя­щие вам. По­сколь­ку по умол­чанию скрипт за­пуска­ет­ся от имени root, он име­ет доступ к ка­та­ло­гу /var для соз­дания pid-фай­ла и жур­на­ла. Вы мо­же­те по­же­лать за­пустить де­мон от имени дру­го­го поль­зо­ва­те­ля – и это воз­мож­но, но тогда файл жур­на­ла сле­ду­ет хранить где-то в дру­гом месте.

Оста­но­ви­те его

Итак, мы за­пусти­ли на­шу коман­ду – а как ее оста­но­вить? Pid-файл пре­достав­ля­ет нам но­мер про­цес­са ра­бо­таю­ще­го скрип­та, а зная но­мер, мож­но про­сто унич­то­жить про­цесс коман­дой kill. За­тем не за­будь­те очи­стить и уда­лить pid-файл, что­бы де­мон мож­но бы­ло за­пустить вновь:

stop)
 	 if [ -f $PIDFILE ]; then
 	 PID=`cat $PIDFILE`
 	 #про­ве­ря­ем за­пу­щен ли про­цесс
 	 if `ps $PID >/dev/null` ; then
 	 kill -HUP $PID
 	 log_success_msg “Process stopped”
 	 else
 	 log_failure_msg “Process not running”
 	 fi
 	 # уда­ля­ем Pid-файлв лю­бом слу­чае
 	 rm $PIDFILE
 	 else
 	 log_failure_msg “Process not running”
 	 fi
 	 ;;

Здесь мы про­ве­ря­ем, что pid-файл су­ще­ству­ет, ина­че счи­та­ем, что про­цесс не за­пу­щен. За­тем из­вле­ка­ем ID про­цес­са при по­мо­щи ма­гии об­рат­но­го апо­ст­ро­фа и про­ве­ря­ем коман­дой ps, что он дей­стви­тель­но су­ще­ству­ет. Ес­ли су­ще­ству­ет, то унич­то­жа­ем [kill] его.

При­менение коман­ды kill – это су­ро­во. Мож­но восполь­зо­вать­ся сиг­на­лом SIGHUP: он веж­ли­во по­про­сит про­цесс уме­реть. Для на­ше­го скрип­та это­го бу­дет доста­точ­но (он от­ра­бо­та­ет оста­ток вы­пол­няю­щей­ся коман­ды sleep и за­кро­ет­ся).

Кро­ме то­го, пе­ред вы­хо­дом сле­ду­ет уда­лить pid-файл. Это не са­мый на­деж­ный скрипт – сле­до­ва­ло бы про­ве­рить, сра­бо­та­ла ли коман­да kill, а уж по­том тру­бить сиг­нал об успеш­ном вы­полнении. Это оз­на­ча­ет ожи­дание и до­полнитель­ную про­вер­ку спи­ска про­цес­сов, а до­ба­влять ее или нет – ре­шать вам.

Мы так­же долж­ны до­ба­вить ука­за­тель ста­ту­са. Это сво­дит­ся лишь к неболь­шой пе­ре­ра­бот­ке бло­ка stop:

status)
 	 if [ -f $PIDFILE ]; then
 	 PID=`cat $PIDFILE`
 	 #про­ве­ря­ем, за­пу­щен ли про­цесс
 	 if `ps $PID >/dev/null` ; then
 	 log_success_msg “Process running”
 	 else
 	 log_warn_msg “Process has failed... removing pidfile”
 	 rm $PIDFILE
 	 fi
 	 else
 	 log_success_msg “Process not running”
 	 fi
 	 ;;

Тут мы до­ба­ви­ли про­вер­ку кор­рект­но­сти pid-фай­ла. Ес­ли все вы­гля­дит так, буд­то про­цесс за­пу­щен, но он не об­на­ру­жи­ва­ет­ся, мы про­сто уда­ля­ем уста­рев­ший pid-файл. Та­кое бы­ва­ет в слу­чае некор­рект­но­го вы­клю­чения ма­ши­ны или ес­ли ка­кая-то коман­да уби­ла наш скрипт.

Дру­гая часто реа­ли­зуе­мая оп­ция в та­ких скрип­тах – restart [пе­ре­за­груз­ка]. В про­стей­шем слу­чае это опе­ра­ция stop, за ко­то­рой сле­ду­ет опе­ра­ция start, и вы мо­же­те лег­ко вы­де­лить ка­ж­дое дей­ствие в функ­цию, а за­тем про­сто объ­е­динить их вме­сте в restart.

Вы най­де­те пол­ную вер­сию скрип­та сле­жения за се­тью на на­шем сай­те http://www.linuxformat.com/files/136bash.zip.

Ес­ли за­пустить пол­ный скрипт локаль­но, вы долж­ны уви­деть

>sh netcheckd status
* Process not running
> sh netcheckd start
* netcheck started
> sh netcheckd status
* Process running
> sh netcheckd stop
* Process stopped
> netcheckd restart
* Process not running
* netcheck started
>

Оста­лось по­местить фай­лы в долж­ные ка­та­ло­ги (/etc/init.d/netcheckd, /usr/bin/netcheck) и, ес­ли по­же­лае­те, до­ба­вить их в спи­сок ав­то­за­пуска. В Ubuntu для это­го про­сто вы­полните:

>sudo update-rc.d netcheckd defaults
Adding system startup for /etc/init.d/netcheckd ...
/etc/rc0.d/K20netcheckd -> ../init.d/netcheckd
/etc/rc1.d/K20netcheckd -> ../init.d/netcheckd
/etc/rc6.d/K20netcheckd -> ../init.d/netcheckd
/etc/rc2.d/S20netcheckd -> ../init.d/netcheckd
/etc/rc3.d/S20netcheckd -> ../init.d/netcheckd
/etc/rc4.d/S20netcheckd -> ../init.d/netcheckd
/etc/rc5.d/S20netcheckd -> ../init.d/netcheckd
>

Точ­ный ме­ха­низм варь­и­ру­ет­ся. В Fedora и Red Hat для то­го же ис­поль­зу­ет­ся chkconfig.

Да, и по­след­нее... ес­ли вы за­хо­ти­те по­экс­пе­ри­мен­ти­ро­вать, де­лай­те все на тес­то­вой или вир­ту­аль­ной ма­ши­не – в кон­це кон­цов, мы же не хо­тим вы­вес­ти из строя ос­нов­ной Linux-ком­пь­ю­тер!

Фай­ло­вые про­вер­ки

Фай­ло­вые про­вер­ки очень час­то ис­поль­зу­ют­ся при соз­да­нии скрип­тов в Bash, и сто­ит за­пом­нить эти, воз­вра­щаю­щие зна­че­ние true или false для кон­ст­рук­ции if. Ес­ли вам такое не по си­лам, за­пом­ни­те хо­тя бы, где на­хо­дит­ся данный спи­сок!

  • -b filename Спе­ци­аль­ный файл блоч­но­го уст­рой­ст­ва.
  • -c filename Спе­ци­аль­ный файл сим­воль­но­го уст­рой­ст­ва.
  • -d directoryname Про­вер­ка су­ще­ст­во­ва­ния ка­та­ло­га.
  • -e filename Про­вер­ка су­ще­ст­во­ва­ния фай­ла.
  • -f filename Про­вер­ка су­ще­ст­во­ва­ния обыч­но­го фай­ла, не ка­та­ло­га.
  • -G filename Про­вер­ка су­ще­ст­во­ва­ния фай­ла и при­над­леж­но­сти груп­пе с те­ку­щим эф­фек­тив­ным ID.
  • -g filename True, ес­ли файл су­ще­ст­ву­ет и ус­та­нов­лен ат­ри­бут set-group-id.
  • -k filename «Лип­кий» бит.
  • -L filename Сим­воль­ная ссыл­ка.
  • -O filename True, ес­ли файл су­ще­ст­ву­ет и при­над­ле­жит поль­зо­ва­те­лю с те­ку­щим эф­фек­тив­ным ID.
  • -r filename Про­вер­ка дос­туп­но­сти фай­ла на чте­ние.
  • -S filename Про­вер­ка, яв­ля­ет­ся ли файл со­ке­том.
  • -s filename Про­вер­ка, что файл име­ет не­ну­ле­вой раз­мер.
  • -u filename Про­вер­ка на­ли­чия би­та set-user-id.
  • -w filename Про­вер­ка дос­туп­но­сти фай­ла на за­пись.
  • -x filename Яв­ля­ет­ся ли файл ис­пол­няе­мым.
Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию