Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Фундаментальные основы Linux. Часть VI. Сценарии

Оригинал: Linux Fundamentals
Автор: Paul Cobbaut
Дата публикации: 16 октября 2014 г.
Перевод: А.Панин
Дата перевода: 21 декабря 2014 г.

Глава 22. Циклы в сценариях

Команда test []

Команда test позволяет установить, является ли какое-либо выражение истинным или ложным. Давайте начнем с проверки, больше ли целочисленное значение 10 целочисленного значения 55.
[paul@RHEL4b ~]$ test 10 -gt 55 ; echo $?
1
[paul@RHEL4b ~]$
Команда test возвращает значение 1, если выражение является ложным. И, как вы увидите в следующем примере, команда test будет возвращать значение 0, если выражение будет являться истинным.
[paul@RHEL4b ~]$ test 56 -gt 55 ; echo $?
0
[paul@RHEL4b ~]$
Если же вам удобнее работать со строками true (истина) и false (ложь), вы можете использовать команду test таким образом, как показано ниже.
[paul@RHEL4b ~]$ test 56 -gt 55 && echo true || echo false
true
[paul@RHEL4b ~]$ test 6 -gt 55 && echo true || echo false
false
Команда test также может заменяться квадратными скобками, поэтому команды из примера ниже полностью аналогичны командам из примера выше.
[paul@RHEL4b ~]$ [ 56 -gt 55 ] && echo true || echo false
true
[paul@RHEL4b ~]$ [ 6 -gt 55 ] && echo true || echo false
false
Ниже приведены примеры реализаций некоторых проверок. Обратитесь к странице руководства man test для ознакомления с дополнительными возможностями реализации различных проверок.
[ -d foo ]             Существует ли директория foo ?
[ -e bar ]             Существует ли файл bar ?
[ '/etc' = $PWD ]      Эквивалентна ли строка /etc значению переменной $PWD ?
[ $1 != 'secret' ]     Отличается ли значение первого параметра сценария от строки secret ?
[ 55 -lt $bar ]        Меньше ли целочисленное значение 55 значения переменной $bar ?
[ $foo -ge 1000 ]      Является ли значение переменной $foo большим или равным целочисленному значению 1000 ?
[ "abc" < $bar ]       Будет ли строка abc расположена выше значения переменной $bar в списке после сортировки ?
[ -f foo ]             Является ли foo обычным файлом ?
[ -r bar ]             Является ли bar читаемым файлом ?
[ foo -nt bar ]        Новее ли файл foo файла bar ?
[ -o nounset ]         Активирован ли параметр командной оболочки nounset ?
Операторы проверок могут комбинироваться с операторами, соответствующими логическим операциям "И" и "ИЛИ".
paul@RHEL4b:~$ [ 66 -gt 55 -a 66 -lt 500 ] && echo true || echo false
true
paul@RHEL4b:~$ [ 66 -gt 55 -a 660 -lt 500 ] && echo true || echo false
false
paul@RHEL4b:~$ [ 66 -gt 55 -o 660 -lt 500 ] && echo true || echo false
true

Условный переход if then else

Конструкция if then else предназначена для выбора варианта кода. В том случае, если определенное условие выполняется, будет исполняться какой либо код, в противном случае будет исполняться какой-либо другой код. В примере ниже осуществляется проверка существования файла, после чего в том случае, если предположение о существовании файла подтверждается, осуществляется вывод соответствующего сообщения.
#!/bin/bash

if [ -f isit.txt ]
then echo файл isit.txt существует!
else echo файл isit.txt не найден!
fi
В том случае, если мы сохраним данный код сценария в файле с именем 'choice', он сможет быть исполнен аналогичным образом.
[paul@RHEL4a scripts]$ ./choice 
файл isit.txt не найден!
[paul@RHEL4a scripts]$ touch isit.txt
[paul@RHEL4a scripts]$ ./choice 
файл isit.txt существует!
[paul@RHEL4a scripts]$

Условный переход if then elif

Вы можете разместить новый оператор условного перехода if внутри блока else, воспользовавшись оператором elif. Ниже приведен простой пример такой записи.
#!/bin/bash
count=42
if [ $count -eq 42 ]
then
  echo "42 является корректным значением."
elif [ $count -gt 42 ]
then
  echo "Слишком много."
else
  echo "Не достаточно."
fi

Цикл for

В примере ниже представлен синтаксис классического цикла for в командной оболочке bash.
for i in 1 2 4
do
   echo $i
done
Пример использования цикла for, скомбинированного с вызовом встраиваемой командной оболочки.
#!/bin/ksh
for counter in `seq 1 20`
do
   echo отсчет от 1 до 20, текущее значение $counter
   sleep 1
done
Сценарий, полностью аналогичный представленному выше, может быть создан и без задействования встраиваемой командной оболочки путем использования реализованного в рамках командной оболочки bash объявления диапазона значений {от значения..до значения}.
#!/bin/bash
for counter in {1..20}
do
   echo отсчет от 1 до 20, текущее значение $counter
   sleep 1
done
В данном цикле for используется механизм поиска файлов по шаблону (реализованный в рамках механизма раскрытия команд). В случае размещения приведенной инструкции непосредственно в командной строке, она будет функционировать аналогично.
kahlan@solexp11$ ls
count.ksh  go.ksh
kahlan@solexp11$ for file in *.ksh ; do cp $file $file.backup ; done
kahlan@solexp11$ ls                                                 
count.ksh  count.ksh.backup  go.ksh  go.ksh.backup 

Цикл while

Ниже приведен простой пример использования цикла while.
i=100;
while [ $i -ge 0 ] ;
do
   echo Обратный отсчет от 100 до 0, текущее значение $i;
   let i--;
done
Бесконечные циклы могут реализовываться с помощью объявлений while true или while : , где символ : является эквивалентом отсутствующей операции в командных оболочках Korn shell и bash.
#!/bin/ksh
# бесконечный цикл
while :
do
 echo hello
 sleep 1
done

Цикл until

Ниже приведен простой пример использования цикла until.
let i=100;
until [ $i -le 0 ] ;
do
   echo Обратный отсчет от 100 до 1, текущее значение $i;
   let i--;
done

Практическое задание: проверки и циклы в сценариях

1. Разработайте сценарий, который будет использовать цикл for для отсчета от 3 до 7.

2. Разработайте сценарий, который будет использовать цикл for для отсчета от 1 до 17000.

3. Разработайте сценарий, который будет использовать цикл while для отсчета от 3 до 7.

4. Разработайте сценарий, который будет использовать цикл until для обратного отсчета от 8 до 4.

5. Разработайте сценарий, который будет производить подсчет файлов с расширением .txt в текущей директории.

6. Используйте оператор if в созданном сценарии для его корректной работы в случае отсутствия файлов с расширением .txt в текущей директории.

Корректная процедура выполнения практического задания: проверки и циклы в сценариях

1. Разработайте сценарий, который будет использовать цикл for для отсчета от 3 до 7.

#!/bin/bash

for i in 3 4 5 6 7
do
 echo Отсчет от 3 до 7, текущее значение $i
done

2. Разработайте сценарий, который будет использовать цикл for для отсчета от 1 до 17000.

#!/bin/bash

for i in `seq 1 17000`
do
 echo Отсчет от 1 до 17000, текущее значение $i
done

3. Разработайте сценарий, который будет использовать цикл while для отсчета от 3 до 7.

#!/bin/bash

i=3
while [ $i -le 7 ]
do
 echo Отсчет от 3 до 7, текущее значение $i
 let i=i+1
done

4. Разработайте сценарий, который будет использовать цикл until для обратного отсчета от 8 до 4.

#!/bin/bash

i=8
until [ $i -lt 4 ]
do
 echo Обратный отсчет от 8 до 4, текущее значение $i
 let i=i-1
done

5. Разработайте сценарий, который будет производить подсчет файлов с расширением .txt в текущей директории.

#!/bin/bash

let i=0
for file in *.txt
do
        let i++
done
echo "В директории $i файлов с расширением .txt"

6. Используйте оператор if в созданном сценарии для его корректной работы в случае отсутствия файлов с расширением .txt в текущей директории.

#!/bin/bash

ls *.txt > /dev/null 2>&1
if [ $? -ne 0 ] 
then echo "В директории 0 файлов с расширением .txt"
else
        let i=0
        for file in *.txt
        do
                let i++
        done
        echo "В директории $i файлов с расширением .txt"
fi


Предыдущий раздел: Оглавление Следующий раздел:
Глава 21. Введение в разработку сценариев   Глава 23. Параметры сценариев