LINUX-BG   Адрес : http://www.linux-bg.org
Писане на скриптове за BASH шел : версия 1.2( част 4)
От: X_console
Публикувана на: 6-06-2000
Адрес на статията: http://www.linux-bg.org/cgi-bin/y/index.pl?page=article&id=advices&key=320090778

Тази статия е преведена с разрешението на автора и X_console.
Адресът на оригиналната статия е http://xfactor.itec.yorku.ca/~xconsole/.

Продължениe на [ част 3 ].

AND и OR
Видяхме как се използват условните оператори и колко полезни са те. Има две допълнителни неща, които могат да бъдат добавени. Условните изрази са AND (или "&&") и OR (или "||"). AND условният израз изглежда по следния начин:

условие_1 && условие_2

AND изразът проверява първо най-лявото условие. Ако условието е вярно се проверява второто условие. Ако и то е вярно се изпълнява останалата част от кода на скрипта. Ако условие условие_1 не е вярно(върне резултат false), тогава условие условие_2 няма да бъде проверено. С други думи:

if(ако) условие_1 е вярно, AND(и) if(ако) условие_2 е вярно, then(тогава)...

Ето един пример с AND условие:

#!/bin/bash
x=5
y=10
if [ "$x" -eq 5 ] && [ "$y" -eq 10 ]; then
echo "I dwete uslowiq sa wqrni."
else
echo "Uslowiqta ne sa wqrni."
fi

Тук виждаме, че x и y имат стойността, за която проверяваме. Променете стойноста на x от x=5 на x=12, след което пуснете отново програмата и ще се убедите, че условието не е изпълнено( връща стойност false).

OR изразът е подобен. Единствената разлика е, че проверява дали най-левият израз не е верен(т.е връща резултат false). Ако това е изпълнено се проверява следващия израз и по-следващия:

условие_1 || условие_2

С други думи това звучи така:

if(ако) условие_1 е вярно, OR(или) ако условие_2 е вярно, тогава...

Ето защо кодът след този условен оператор ще бъде изпълнен ако поне едно от условията е вярно:

#!/bin/bash
x=3
y=2
if [ "$x" -eq 5 ] || [ "$y" -eq 2 ]; then
echo "Edno ot uslowiqta e wqrno."
else
echo "Nito edno ot uslowiqta ne e wqrno."
fi

В този пример ще се уверите, че едно от условията е вярно. Сменете стойността на променливата y и изпълнете отново програмата. Ще видите, че нито едно от условията не е вярно.

Ако се замислите, ще видите, че условният оператор if може да замести употребата на AND и OR изразите. Това става чрез използването на вложени if оператори. "Влагане на if оператори" означава да използваме if оператор в тялото на друг if оператор. Можете да правите влагане и на други оператори, а не само на if. Ето един пример с вложени ifоператори, които заместват използването на AND израз в кода на програмата:

#!/bin/bash
x=5
y=10
if [ "$x" -eq 5 ]; then
if [ "$y" -eq 10 ]; then
echo "I dwete uslowiq sa wqrni."
else
echo "Uslowiqta ne sa wqrni."
fi
fi

Резултатът е същият, както и ако използвахме AND израз. Проблемът е, че кодът става по - трудно четим и отнема повече време, за да се напише. За да се предпазите от проблеми използвайте AND и OR изрази.

Използване на аргументи
Може би сте забелязали, че повечето програми в Linux не са интерактивни. От Вас се иска да въведете някакви аргументи; в противен случай получавате съобщение, в което се обяснява как да използвате програмата. Вземете за пример командата more. Ако не напишете име на файл след нея, резултатът ще бъде точно едно такова помощно съобщение. Възможно е да направите вашата шел програма да използва аргументи. За тази цел трябва да използвате специалната променлива "$#". Тази променлива съдържа общия брой на всички аргументи подадени на програмата. Например ако изпълните следната програма:

xconsole$ foo argument

$# ще има стойност 1 , защото има само един аргумент подаден на програмата. Ако имате два аргумента, тогава $# ще има стойност 2. В допълнение стойността на всеки аргумент (нулевият аргумент е винаги името на програма - foo) може да се вземе като използвате променливите $0 - за името на програмата в случая foo, $1 за стойноста на първият аргумент -argument и т.н. Може да имате максимум 9 такива променливи от $0 до $9. Нека да видим това в действие:

#!/bin/bash
# izpechataj pyrwiq argument
# proweri dali ima pone edin argument:
if [ "$#" -ne 1 ]; then
echo "usage: $0 "
fi

echo "Stojnosta na argumenta e $1"

Тази програма очаква един и само един аргумент, за да тръгне. Ако я стартирате без аргументи, или подадете повече от един аргумент, програмата ще изпечата съобщение за това как да се използва. В случай, че имаме само един аргумент шел програмата ще отпечата стойноста на аргумента, който сте подали. Припомнете си, че $0 е името на програмата. Ето защо тази специална променлива се използва в "usage" съобщението.

Пренасочване и PIPING
Обикновено, когато стартирате дадена команда, резултатът от изпълнението се отпечатва на екрана. Например:

xconsole$ echo "Hello World"
Hello World

"Пренасочването" Ви позволява да съхраните резултата от изпълнението някъде другаде. В повечето случаи това става към файл. Операторът ">" се използва за пренасочване на изхода. Мислете за него като за стрелка, сочеща къде да отиде резултата. Ето един пример за пренасочване на изхода към файл:

xconsole$ echo "Hello World" > foo.file
xconsole$ cat foo.file
Hello World

Тук резултатът от командата echo "Hello World" е пренасочен към файл с име foo.file. Когато прочетете съдържанието на файла ще видите там резултата. Има един проблем, когато използвате оператора ">". Ако имате файл със същото име, то неговото съдържание няма да бъде запазено, а ще бъде изтрито и заместено с новото. Ами ако искате да добавите информация във файла, без да изтривате старата? Тогава трябва да използвате операторът за добавяне : ">>". Използва се по същия начин с тази разлика, че не изтрива старото съдържание на файла, а го запазва и добавя новото съдържание накрая.

А сега ще ви запознаем с piping. Piping-ът Ви позволява да вземете резултата от изпълнението на дадена програма и да го използвате като входни данни за друга програма. Piping става посредством оператора: "|". Забележете, че това не е малката буквата "L". Този оператор може да получите чрез натискане на клавиша SHIFT и \. Ето и един пример за piping:

xconsole$ cat /etc/passwd | grep xconsole
xconsole:x:1002:100:X_console,,,:/home/xconsole:/bin/bash

Тук четем целия файл /etc/passwd и след това резултатът е подаден за обработка на командата grep, която от своя страна претърсва текста за низа xconsole и изпечатва целия ред, съдържащ този низ на екрана. Може да използвате и пренасочване, за да запишете крайния резултат на файл:

xconsole$ cat /etc/passwd | grep xconsole > foo.file
xconsole$ cat foo.file
xconsole:x:1002:100:X_console,,,:/home/xconsole:/bin/bash

Работи. Файлът /etc/passwd е прочетен и неговото съдържание е претърсено от командата grep за низа xconsole. След което крайният резултат е пренасочен към файл foo.file. Ще откриете, че пренасочване и piping са много полезни средства, когато пишете Вашите шел програми.

Временни файлове
Често ще има моменти, в които ще Ви се наложи да създадете временен файл. Този файл може да съдържа временна информация и просто да работи с някоя програма. В повечето случаи със завършването на изпълнението на програмата се изтрива и временният файл. Когато създадете файл трябва да му зададете име. Проблемът е, че името на файла, който създавате не трябва да съществува в директорията, в която го създавате. В противен случай може да затриете важна информация. За да създадете файл с уникално име трябва да използвате "$$" символа като представка или надставка в името на файла. Вземете за пример следния случай: искате да създадете временен файл с име hello. Има вероятност и някой друг да има файл със същото име в тази директория, което ще доведе до катастрофални резултати за Вашата програма. Ако вместо това създадете фиайл с име hello.$$ или $$hello, Вие ще създадете уникален файл. Опитайте:

xconsole$ touch hello
xconsole$ ls
hello
xconsole$ touch hello.$$
xconsole$ ls
hello hello.689

Ето го и нашият временен файл.

Връщане на стойности
Повечето програми връщат стойност(и) в зависимост от начина, по който завършват изпълнението си. Например, ако разгледате ръководството на командата grep ще видите, че в него се казва, че командата grep връща стойност 0 ако има съвпадение, и 1 ако не е открито съвпадение. Защо да се грижим да връщаме стойности? По много причини. Нека да кажем, че искате да проверите дали конкретно потребителско име съществува на Вашата система. Единият от начините да направите това е да използвате командата grep върху файла с паролите /etc/passwd. Да предположим, че потребителското име, което търсим е foobar:

xconsole$ grep "foobar" /etc/passwd
xconsole$

Няма никакъв резултат от изпълнението. Това означава че grep не е намерила съвпадение. Но може да направим програмата много по-полезна ако се появява съобщение, което пояснява резултата. Това е, когато искате да проверите стойноста, която се връща от дадена програма. Има една специална променлива, която съдържа крайния резултат от изпълнението на програмата. Тази променлива е $?.Разгледайте следния код:

#!/bin/bash
# grep for user foobar and pipe all output to /dev/null:
grep "foobar" /etc/passwd > /dev/null 2>&1
# capture the return value and act accordingly:
if [ "$?" -eq 0 ]; then
echo "Match found."
exit
else
echo "No match found."
fi

Когато стартираме програмата, променливата "$?" ще прихване резултата от командата grep. Ако той е равен на 0, значи има съвпадение и подходящо съобщение ще обяви за това. В противен случай ще изпечата, че няма съвпадения. Това е един основен начин за получаване на резултата, който връща дадена програма. Ще откриете, че доста често ще Ви се наложи да знаете стойността, която връща дадена програма, за да продължите по-нататък.

Ако случайно се чудите какво значи 2>&1, сега ще ви обясня . Под Linux, тези номера обозначават файлови дескриптори. 0 е за стандартния вход (пример: клавиатура), 1 е за стандартния изход (пример: монитор) и 2 е за стандартния изход на грешките (пример: монитор). Всяка обикновена информация се изпраща на файлов дескриптор 1, и ако има грешки те се изпращат на файлов дескриптор 2. Ако не искате тези съобщения да излизат просто можете да ги пренасочите към /dev/null. Забележете, че това няма да спре изпращането на информацията на стандартния изход. Например, ако нямате права да четете от директория на друг потребител, Вие няма да можете да видите нейното съдържание:

xconsole$ ls /root
ls: /root: Permission denied
xconsole$ ls /root 2> /dev/null
xconsole$

Както виждате, съобщението за грешка не беше изпечатано. Същото важи както за други програми, така и за файлов дескриптор 1. Ако не искате резултатът от изпълнението на програмата да се отпечатва на екрана, можете спокойно да го пренасочите към /dev/null. Ако не искате да виждате както резултатът от изпълнението, така и съобщенията за грешка, може да го направите по следния начин:

xconsole$ ls /root > /dev/null 2>&1

Това означава че резултатът от програмата, както и всяка грешка, която предизвика тази програма ще бъдат изпратени на /dev/null, така че никога повече няма да можете да ги видите.

Какво трябва да направите ако искате Вашият шел скрипт да връща стойност при завършване на програмата? Командата exit приема само един аргумент - число, което трябва да се върне при завършване на програмата. Обикновно числото 0 се използва, за да кажем, че програмата е завършила успешно, т.е. не е възникнала никаква грешка по време на нейното изпълнение. Всичко по-голямо или по-малко от 0 обикновено обозначава, че е възникнала някаква грешка. Това го решавате Вие като програмист. Нека проследим следната програма:

#!/bin/bash
if [ -f "/etc/passwd" ]; then
echo "Password file exists."
exit 0
else
echo "No such file."
exit 1
fi

Заключение
С това завършихме увода в bash програмирането. Това ръководство Ви дава основните знания, за да можете да редактирате чужди bash скриптове или да създавате нови. За да постигнете съвършенство обаче, трябва много да практикувате. bash е идеално средство за писане на обикновени административни скриптове. Но за по-големи разработки ще се нуждаете от мощни езици като C или Perl.

Успех!

X_console

Вижте [ Част 1| Част 2 | Част 3 | Част 4 ]


<< Кирилизиране на Linux | (Не)сигурност с Apache Web Server >>

Авторите на сайта, както и техните сътрудници запазват авторските права върху собствените си материали публикувани тук, но те са copyleft т.е. могат свободно да бъдат копирани и разпространявани с изискването изрично да се упоменава името на автора, както и да се публикува на видно място, че те са взети от оригиналния им URL-адрес на този сървър (http://www.linux-bg.org). Авторските права на преводните материали принадлежат на техните автори. Ако с публикуването тук на някакъв материал неволно са нарушени нечии права - след констатирането на този факт материалът ще бъде свален.

All trademarks, logos and copyrights mentioned on this site are the property of their respective owners.
Linux is copyright by Linus Torvalds.
© Линукс за българи ЕООД 2007
© Slavei Karadjov 1999 - 2006

All rights reserved.

Изпълнението отне: 0 wallclock secs ( 0.19 usr + 0.02 sys = 0.21 CPU)