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

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

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

Условни оператори
Условните оператори ви позволяват вашата програма да "взема решения" и я правят по-компактна. Което е по-важно с тях може да проверявате за грешки. Всички примери до сега започваха изпълнението си от първия ред до последния без никакви проверки. За пример:

#!/bin/bash
cp /etc/foo .
echo "Done."

Тази малка шел програма  копира файлът /etc/foo в текущата директория и изпечатва "Done" на екрана. Тази програма ще работи само при едно условие. Трябва да има файл /etc/foo. В противен случай ще се получи следния резултат:

xconsole$ ./bar.sh
cp: /etc/foo: No such file or directory
Done.

Както виждате имаме проблем. Не всеки който стартира вашата програма има файл /etc/foo на системата си. Ще бъде по-добре, ако вашата програма проверява дали файла /etc/foo съществува и ако това е така да продължи с копирането, в противен случай да спре изпълнението. С "псевдо" код това изглежда така:

if /etc/code exists, then
    copy /etc/code to the current directory
    print "Done." to the screen.
otherwise,
    print "This file does not exist." to the screen
    exit

Може ли това да бъде направено с bash? Разбира се! В bash условните оператори са: if, while, until, for, и case.   Всеки оператор започва с ключова дума и завършва с ключова дума. Например if оператора започва с ключовата дума if, и завършва с  fi. Условните оператори не са програми във вашата система. Те са вградени свойства на  bash.

if ... else ... elif ... fi
Е един от най-често използваните условни оператори. Той дава възможност на програма да вземе решения от рода на "направи това ако(if) това условие е изпълнено, или(else)   прави нещо друго". За да използвате ефективно условния оператор if трябва да използвате командата test. test проверява за съществуване на файл, права, подобия или разлики. Ето програмата bar.sh:

#!/bin/bash
if test -f /etc/foo
then
    # file exists, so copy and print a message.
    cp /etc/foo .
    echo "Done."
else
    # file does NOT exist, so we print a message and exit.
    echo "This file does not exist."
    exit
fi

Забележете че редовете след  then и else са малко по-навътре. Това не е задължително, но се прави с цел програмата да бъде по-лесна за четене. Сега стартирайте програмата. Ако имате файл /etc/foo, тогава програмата ще го копира в текущата директория, в противен случай ще върне съобщение за грешка. Опцията  -f проверява дали това е обикновен файл. Ето списък с опциите на  командата test:

-d проверява дали файлът е директория
-e проверява дали файлът съществува
-f проверява дали файлът е обикновен файл
-g проверява дали файлът има SGID права
-r проверява дали файлът може да се чете
-s проверява дали файлът разнерът на файла не е 0
-u проверява дали файлът има SUID права
-w проверява дали върху файлът може да се пише
-x проверява дали файлът е изпълним

else се използва ако искате вашата програма да направи нещо друго, ако първото условие не е изпълнено. Има и ключова дума elif, която може да бъде използвана вместо да пишете друг if вътре в първия ifelif идва от английското "else if". Използва се когато първото условие не е изпълнено и искате да проверите за друго условие.

Ако не се чувствате комфортно с  if и test синтаксиса, който е :

if test -f /etc/foo
then

тогава може да използвате следния вариант:

if [ -f /etc/foo ]; then

Квадратните скоби формират  test командата. Ако имате опит в програмирането на C този синтакс може да ви се стори по-удобен. Забележете, че трябва да има разстояние след отварящата квадратна скоба и преди затварящата. Точката и запетаята: ";" казва на шела че това е края на командата. Всичко след ";" ще бъде изпълнено сякаш се намира на следващия ред. Това прави програмата малко по-четима. Можете разбира се да сложите  then на следващия ред.

Когато използваме променливи с  test е добре да ги заградим с кавички. Например:

if [ "$name" -eq 5 ]; then

while ... do ... done
while оператора е условен оператор за цикъл. Най-общо казано, това което прави е  "while(докато) това условие е вярно, do(изпълни) командите done ". Нека да видим следния пример:

#!/bin/bash
while true; do
   echo "Press CTRL-C to quit."
done

true в действителност е програма. Това което прави тази програма е да се изпълнява безкрайно. Използването на  true се смята, че забавя вашата програма, защото шел интерпретатора първо трябва да извика програмата и след това да я изпълни. Вместо това може да използвате командата ":":

#!/bin/bash
while :; do
   echo "Press CTRL-C to quit."
done

По този начин вие постигате същия резултат, но доста по бързо. Единствения недостатък е, че програмата става по-трудно четима.  Ето един по-подробен пример, който използва променливи:

#!/bin/bash
x=0;     # initialize x to 0
while [ "$x" -le 10 ]; do
    echo "Current value of x: $x"
    # increment the value of x:
    x=$(expr $x + 1)
    sleep 1
done

Както виждате използваме  test (записана като квадратни скоби) за да проверим състоянието на променливата  x. Опцията  -le проверява дали  x е по-малко(less) или равно(equal) на 10. На говорим език това се превежда по следния начин "Докато(while) x е по-малко или равно на 10, покажи текущата стойност на x, и след това добави 1 към текущата стойност на x.". sleep 1  казва на програмата да спре изпълнението си за една секунда. Както виждате това което правим тук в да проверим за равенство. Ето списък с някой опции на test:

Проверка за равенства между променливите x и y, ако променливите са  числа:
x -eq y   Проверява дали  x е равно на  y
x -ne y   Проверява дали  x не е равно на y
x -gt y   Проверява дали x е по-голямо от y
x -lt y   Проверява дали x е по-малко от y

Проверка за равенства между променливите x и y, ако променливите са  текст:
x = y   Проверява дали  x е същитата като  y
x != y   Проверява дали  x не е същитата като  y
-n x   Проверява дали x не е празен текст
-z x   Проверява дали x  е празен текст

От горния пример единственият ред, който може да ви се стори по-труден за рабиране е следния:

x=$(expr $x + 1)

Това което прави този ред е да увеличи стойноста на  x с 1. Но какво значи $(...)? Дали е променлива? Не. На практика това е начин да кажете на  шел интерпретатора, че ще изпълнявате командата expr $x + 1, и резултата от тази команда ще бъде присвоен на x. Всяка команда която бъде записана в  $(...) ще бъде изпълнена:

#!/bin/bash
me=$(whoami)
echo "I am $me."

Опитайте с този пример за да разберете какво имам предвид. Горната програмка може да бъде написана по-следния начин:

#!/bin/bash
echo "I am $(whoami)."

Сами си решете кой от начините е по-лесен за вас. Има и друг начин да изпълните команда или да присвоите разултата от изпълнението на дадена команда на променлива. Този начин ще бъде обяснен по-нататък. За сега използвайте $(...).

until ... do ... done
Условния оператор until е много близък до while. Единствената разлика е, че се обръща смисъла на условието и се взима предвид новото значение. Действието на until оператора е "докато(until) това условие е вярно, изпълнявай(do) командите". Ето пример:

#!/bin/bash
x=0
until [ "$x" -ge 10 ]; do
    echo "Current value of x: $x"
    x=$(expr $x + 1)
    sleep 1
done

Този код може би ви изглежда познат. Проверете го и вижте какво прави.  until ще изпълнява командите докато стойноста на променливата x е по-голяма или равна на 10. Когато стойноста на x стане 10 цикълът ще спре. Ето защо последната стойност на x която ще се изпечата е  9.

for ... in ... do ... done
for се използва кога искате да присвойте на дадена променлива набор от стойности. Например можете да напишете програма, която да изпечатва 10 точки всяка секунда:

#!/bin/bash
echo -n "Checking system for errors"
for dots in 1 2 3 4 5 6 7 8 9 10; do
    echo -n "."
done
echo "System clean."

В случай, че не знаете опцията  -n на командата echo спира автоматичното добавяне на нов ред. Пробвайте командата веднъж с   -n опцията и веднъж без нея за да разберете за какво става дума. Променливата dots преминава през стойностите от 1 до 10.  Вижте следния пример:

#!/bin/bash
for x in paper pencil pen; do
    echo "The value of variable x is: $x"
    sleep 1
done

Когато стартирате програмата ще видите че x в началото ще има стойност paper, след което ще премине на следващата стойност, която е pencil, и след това pen. Когато свършат стойностите през който минава цикъла изпълненито му завършва.

Ето една доста полезна програма. Тя добавя .html разширение на всички файлове в текущата директория:

#!/bin/bash
for file in *; do
    echo "Adding .html extension to $file..."
    mv $file $file.html
    sleep 1
done

Ако не знаете "*" е "wild card character". Това ще рече "всичко в текущата директория", което в нашия случай представлява всички файлове в тази директория. Променливата file ще премине през всички стойности, в този случай файловете в текущата директория. След което командата mv преименува стойностите на променливата file във такива с  .html разширение.

case ... in ... esac
Условния оператор case е близък до  if . За предпочитане е да се използва когато имаме голям брой условия който трябва да бъдат проверени. Вземете за пример следния код:

#!/bin/bash
x=5     # initialize x to 5
# now check the value of x:
case $x in
   0) echo "Value of x is 0."
      ;;
   5) echo "Value of x is 5."
      ;;
   9) echo "Value of x is 9."
      ;;
   *) echo "Unrecognized value."
esac

Оператора case ще провери стойност на  x на коя от  3-те възможности отговаря. В този случай първо ще провери дали стойноста на x е 0, след което ще провери за 5 и 9. Накая ако никое от условия не е изпълнено ще се изпечата съобшението "Unrecognized value.". Имайте предвид, че "*" означава "всичко", и в този случай това означава "която и да е стойност различна от посочените". Ако стойноста на  x е различна от 0, 5, или 9, то тогава тя попада в случая "*". Когато използвате  case всяко условие трябва да завършва с две ";". Може би се чудите защо да използвате  case когато може да използвате if? Ето как изглежда еквивалентната програма написана с  if. Вижте коя програма е по-бърза и по лесна за четене:

#!/bin/bash
x=5     # initialize x to 5
if [ "$x" -eq 0 ]; then
    echo "Value of x is 0."
elif [ "$x" -eq 5 ]; then
    echo "Value of x is 5."
elif [ "$x" -eq 9 ]; then
    echo "Value of x is 9."
else
    echo "Unrecognized value."
fi

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


<< Писане на скриптове за BASH шел : версия 1.2( част 3) | Безплатни шел акаунти >>

Авторите на сайта, както и техните сътрудници запазват авторските права върху собствените си материали публикувани тук, но те са 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.21 usr + 0.01 sys = 0.22 CPU)