Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Операционные системы. Часть 1. Операционная система Linux. Практикум

.pdf
Скачиваний:
1
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
☆
41
Таблица 5. Специальные последовательности формата командной строки.
Послед.
Выводимое значение
\t
время в формате часы: минуты: секунды
\d
дата в формате день_недели месяц число
\n
перевод строки
\s
имя оболочки, базовое имя $0 (участок, следующий за конечным /)
\w
текущий рабочий каталог
\W
базовое имя $PWD
\u
имя текущего пользователя
\h
сетевое имя компьютера
\#
номер этой команды
\!
номер истории этой команды
\nnn
символ, имеющий код равный nnn в восмиричной системе
\$
если uid=0, то \#, иначе \$.
\\
обратная косая черта (backslash).
\[
начало терминальной последовательности
\]
конец терминальной последовательности
Чтобы изменить формат приглашения командной оболочки достаточно присвоить необходимое значение соответствующей переменной. Например, выделить текущего пользователя зелѐным цветом можно, присвоив переменной PS1 следующее значение:
PS1=[\[\033[32m\]\u\[\033[0m\]@\h \W]\$
4.13. Получение информации от пользователя
При необходимости командная оболочка позволяет сформировать значение некоторой переменной «спросив» его у пользователя. Для этого используется команда read, которой в качестве пераметра передаѐтся имя требуемой переменной.
[student@wp1 student]$read CHOICE
Привет !!!<ENTER>
[student@wp1 student]$echo “Вы ввели “${CHOICE}
Привет !!!
[student@wp1 student]$_
Чтобы указать какое приглашение должно быть выведно в строке для ввода можно использовать параметр –p. Например, read –p “Введите X” X.
Время ожидания (в секундах) ввода задаѐтся или при помоци переменной TMOUT или при помощи параметра –t. Если переменная TMOUT неопределена, или еѐ значение равно 0 и не указан параметр -t, то время ожидания считается бесконечным. Обратите внимание, что значение
42
переменной TMOUT также влияет на время ожидания командной оболочкой
Таблица 6. Некоторые параметры команды test
Выражение
Значение
-d файл
существует ли файл и является ли он каталогом?
-e файл
существует ли указанный файл?
-f файл
существует ли файл и является ли он обычным файлом?
-L файл
существует ли файл и символьная ли он ссылка?
-r файл
существует ли файл и разрешен ли он для чтения?
-s файл
существует ли файл и имеет ли он нулевой размер?
очередной команды !!!
Используя параметр –s можно запретить отображение вводимых символов на экране. Это удобно, например, при вводе паролей.
4.14. Управляющие структуры
Командная оболочка bash позволяет организовать ветвление программы в зависимости от различных условий.
4.14.1. Условный оператор if-fi
Выражеиние if записывается следующем образом28:
$if выражени1 ; then \
>выражение2 ; \
>elif выражение3 ; then \
>выражение4 ; \
>else \
>выражение5 ; \
>fi<ENTER>
В приведенной выше команде if сначала выполняется выражение1. Если код завершения выражения1 равен 0 (что интерпретируется как его истинность), то выполняется выражение2 и команда if заканчивается. В противном случае выполняется выражение3 и проверяется код завершени. Если выражение3 возвращает значение равное 0, то выполняется выражение4 и команда if. Если выражение3 возвращает ненулевое значение, то выполняется выражение5. Наличие операторов elif и else необязательно. В блоке if-fi может содержаться несколько elif.
Часто в блоке if-fi в качестве выражений, результаты которых проверяются, используется команда test, которая имеет две формы записи:
test параметры или [ параметры ]. После интерпретации параметров (таблица
6) как логического выражения команда test возвращает значение 0 - истина, либо 1 - ложь.
28
щей только из символа $.
В дальнейшем по тексту будем использовать сокращенный формат приглашения командной строки, состоя-
43
-w файл
существует ли файл и разрешена ли в него запись?
-x файл
существует ли файл и является ли он исполняемым?
-O файл
существует ли файл и приналежит ли он текущему пользователю?
файл1 -nt файл2
Были ли файл1 последний раз модифицирован позже, чем файл2?
-z строка
указанная строка имеет нулевую длинну?
-n строка
указанная строка имеет ненулевую длинну?
стр1 == стр2
указанные строки совпадают?
! выражение
указанное выражение false?(содержит не ноль)
выр1 -a выр2
Логическое AND двух выражений
выр1 -o выр2
Логическое OR двух выражений
выр1 -eq выр2
выр1 равно выр2?
выр1 -ne выр2
выр1 неравно выр2?
выр1 -lt выр2
выр1 меньше (в арифметическом смысле) выр2?
выр1 -le выр2
выр1 меньше либо равно выр2?
выр1 -gt выр2
выр2 меньше выр1?
выр1 -ge выр2
выр2 меньше либо равно выр1?
Ниже приведены примеры использования команды test в составе выражения if--fi:
$if [ -d $HOME/bin ] ; then \ >PATH="$PATH:$HOME/bin" ; fi $if [ -z "$DTHOME" ] && [-d /home/student/dt ] ;then \ >DTHOME=/home/student/dt ; \ >fi $if [ -z "$DTHOME" -a -d /home/student/dt ] ; then \ >DTHOME=/home/student/dt ; \ >fi
В первом примере проверяется существует ли каталог $HOME/bin, и, если он существует, то он добавляется к переменной PATH.
Во втором и третьем случае проверяется установлено ли значение переменной DTHOME и существует ли каталог /home/student/dt. Если переменная неопределена, или имеет пустое значение и указанный каталог существует, то переменной DTHOME задаѐтся новое значение. Во втором примере проверка указанного условия происходит с использованием списка из двух команд test, выполняемых по условию «И». В третьем примере используется один вызов команды test, в параметрах которой указано все условие (условие «И» реализуется с помощью опции –a).
Следует обратить внимание, что при проверки значения переменной DTHOME она взята в кавычки. Это сделано так потому, что если переменная всетаки неопределена или определена, но не имеет значения, то вместо неѐ в командную строку ничего не будет подставлено. Если кавычки не использовать, то после подстановки потеряется второй параметр команды test и
44
нечего будет проверять (т.е. строка test –z $DTHOME будет преобразована к виду test –z).
4.14.2. Оператор множественного выбора case-esac
Блок case-esac аналогичен оператору if-fi с множеством elfi и предназначен для проверки одной переменной на несколько возможных значений. Блок case-esac записывается следющим образом:
$case значение in \
>шаблон1) \
>список команд1 ;;
>шаблон2) \
>список команд2 ;;
>esac<ENTER>
В данном случае значение - это строка символов, сравниваемая с шаблоном до тех пор, пока она не совпадет с ним. Список команд, следующий за шаблоном, которому удовлетворяет значение, запускается на выполнение. За списком следует команда ;;, которая завершает работу блока case-esac.
Если значение не удовлетворяет ни одному из шаблонов, выражение case завершается. Если необходимо выполнить какие-то действия по умолчанию, следует включить в выражение шаблон ''*'', которому удовлетворяет любое значению.
В выражении case-esac должен присутсвовать по крайней мере один шаблон. Максимальное число шаблонов неограничено.
Шаблон формируется по правиалам аналогичным именам файлов и каталогов (с учетов символов расширения), а также оператор дизъюнкции ''|'' (операция или). Ниже приведен пример использования блока case-esac:
$case "$TERM" in \
>*term) \
>TERM = xterm \
>;; \
>network | dialup | unknown | vt[0-9]*) \
>TERM=vt100 \
>;; \
>esac
4.15. Циклические конструкции
Циклические конструкции применяются в том случае, когда надо многократно повторить одни и те же действия.
4.15.1. Цикл for
Цикл for предназначен для выполнения определѐнных действия над несколькими данными. Формат записи цикла следующий:
45
$for имя_переменной in список_значений ; \
>do \
>команда1 ; команда2 ...\
>done
В цикле for переменной с указаным именем последовательно присваиваются все значения из списка_значений и для каждого из этих значений выполняется список_команд. Значения в списке_значений перечисляются через пробел. Например следующая команда выдаст на экран десять строк: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
$for i in 1 2 3 4 5 6 7 8 9 10 ; \
>do \
>echo $i ; \
>done
4.15.2. Цикл while
Если необходимо выполнять какие-либо действия до тех пор, пока истино некоторое выражение, то следует использовать цикл while, который записывается следующим образом:
$while выражение ; \
>do \
>список_команд ; \
>done
На каждой итерации этого цикла выполняется выражение и до тех пор, пока он возвращает значение 0, выполняется список_команд. Если в качестве выражения указать команду /bin/true, то цикл будет бесконечным, и завершить его можно только используя оператор break. Пропустить какую-либо часть цикла и перейти на следуюшую его итерацию можно используюя в списке_команд команду continue.
Например, вывод последовательности цифр от 1 до 9 можно организовать следующим образом:
$x=1
$while [ $x -lt 10 ] ; \
>do \
>echo $x ; \
>x=$(( $x+1 )) ; \
>done
4.15.3. Цикл until
Если необходимо выполнять какие-либо действия до тех пор, пока ложно некоторое выражение, то следует использовать цикл until, записываемый следующим образом:
46
$until выражение ; \
>do \
>список_команд ; \
>done
На каждой итерации этого цикла выполняется выражение и до тех пор, пока он возвращает значение отличное от 0, выполняется список_команд. Если в качестве выражения указать команду /bin/false, то цикл будет бесконечным, и завершить его можно только используя оператор break.
Например, вывод последовательности цифр от 1 до 9 можно организовать следующим образом:
$x = 1
$until [ $x -ge 10 ] ; \
>do \
>echo $x ; \
>x=$(( $x+1 )) ; \
>done
4.15.4. Цикл select
Если имеется набор значений и требуется по желанию пользоваться над некоторыми из них выполнить некоторые операции, то используется цикл select, который позволяет создать нумерованное меню значений, пункты которого могут быть выбраны пользователем. Данный цикл записывается следующим образом:
$select имя_переменной in список_значений ; \
>do \
>список_команд ; \
>done
При запуске цикла select в сандартный поток ошибок выводится список_значений. Перед каждым пунктом отображается номер, который и предлагается выбрать пользователю. Затем выводится приглашение ввода номера. Формат приглашения определяется переменной PS3. Выбрав номер пункта, пользователь вводит его с клавиатуры. После этого, для указанного элемента спика значений (который помещается в указанную переменную) выполняется список_команд. После этого опять выводится меню цикла select.
Завершить цикл select можно либо после ввода EOF (нажатия комбинации клавиш <CTRL+D>), либо при помощи команды break. Пример использования цикла select:
$select file in ./*.c ; \
>do\
>gcc –Wall -ansi $file –o `basename $file .c` ; \
>done
47
В данном примере пользователю предлагается выбрать один из файлов с суффиксом .c, расположенных в текущем каталоге. Выбранный файл будет скомпилировать и результат компиляции помещѐн в файл с таким же именем, но без суффикса .c. Имя файла результата формируется командой basename29, результат которой подставляется в команду компиляции.
4.16. Группирование команд. Функции. Скрипты.
Командная оболочка BASH позволяет группировать несколько команд, выполняющих определенное действие, в функции или специальные файлы, называемые скриптами.
Функции опрделеяется так:
$function имя () { список_команд ; }
В дальнейшем, если будет дана команда имя, то вместо неѐ будет выполнен список_команд. Например30,
$ls
$function ls () { /bin/ls –A $@ ; }
$ls
. ..
Здесь объявляется функция с именем ls, которая содержит всего-лишь одну команду /bin/ls с соответсвующими параметрами. До того, как определена эта функция команда ls привозит к запуску файла /bin/ls, выводящего на экран содержимое каталога.
Скрипт – это обычный текстовый файл31, содержащий команды оболочки. Такой файл может быть запущен на исполнение следующим образом:
$bash имя_файла
Другими словами, для выполнения скрипта необходимо запустить командную оболочку, передав ей в качестве параметра имя соответвующего файла.
Другой вариант запуска скрипта - просто указав его имя в командной оболочки (т.е. сделав из него некий вид программы). Для этого надо в параметрах доступа определить файл как исполняемый, и в первых строках этого файла явно указать оболочку, для которой предназначен этот скрипт следующем образом:
#!оболочка
29 30 31
Подробнее о команде basename смотрите в электронном справочнике man. Значение переменной @ смотри ниже. Обычно такие файлы имею суффикс .sh
48
В общем случае символ # в скрипте означает комментарий, требующий
Таблица 7. Специальные переменные, используемые в скриптах
Перем
Значение
$0
Имя выполняемой команды. Для скрипта -- это путь, указанный при его вызове. Для функции – имя оболочки.
$n
Переменные, соответсвующие параметрам, заданным при вызове сценария. Здесь n - десятичное число, соответсвующее номеру параметра. (Первый параметр $1, второй $2 и т.д.)
$#
Число параметров, указанных при вызове сценария.
$*
Строка параметров, заключенная в двойные кавычки.
$@
Все параметры, каждый заключен в двойные кавычки
$?
Статус завершения последней выполненной команды.
$$
Номер процесса, соответсвующего текущей оболочке.
$!
Номер процесса, соответсвующий команде, запущенной в фоновом режиме.
игнорировать строку. Однако ели он является первым символом файла и за ним следует символ !, то это означает "магическую комбинацию", за которой указывается путь к файлу, который должен быить использован в качестве интерпретатора (например, /bin/bash, /bin/perl, /bin/sh и т.д). Встретив такую комбинацию командная оболочка запустить соответсвуюший файл и передаст ей имя файла в качестве параметра.
Скрипт, в свою очередь, может содержать все конструкции описанные ранее (в том числе и функции).
Выполнение скрипт происходит построчно. При этом, если конструкция включает в себя несколько команд, то они могут располагатья на нескольких строках и указывать символ \ в конце неоконченной строки при этом нет необходимости. Например,
#!/bin/bash
X=1
read –p “Введите X = “ X
if [ $X –lt 0 ] ; then
echo “Вы ввели отрицательное число”
else
echo “Вы ввели положительное число”
fi
4.17. Анализ опций, передаваемых группе команд (функции и скрипту)
Любому скрипту, точто также как и функции, могут быть переданы параметры (так как это делается при запуске любой команды). Передаются параметры в виде специальных переменных (таблица 7).
Последователь просмотреть параметры командной строки можно используя следующую конструкцию:
49
#!/bin/bash
while [ -n “$1” ] ; do
echo “Имеется параметр – “$1
shift
done
Параметры просматриваются в цикле while, условием выполнения которого является результат команды test с параметрами, требующими, чтобы длинны строки “$1” была отлично от нуля. В строку подставляется значение первого параметра. Если параметр не указан, то переменная $1 имеет пустое значение, соответсвенно строка будет иметь нулевую длинну и цикл сразу же прекратиться. Если параметр указан, то он выводится в теле цикла и затем выполняется команда shift, которая изменяет переменные $n сдвигая их на одну влево (т.е. $1=$2, $2=$3 и т.д.). Значение первого параметра при этом теряется. Когда сдвигается последний параметр, то переменной $1 присваивается пустое значение (так как следующей за ней переменной несуществует). В качестве пераметра команды shift можно указать на сколько требуется сдвинуть строку параметров. Например, shift 2 приведѐт к следующему изменению: $1=$3, $2=$4 и т.п.
Если требуется определить есть ли в параметрах определѐнные короткие опции, то можно использовать специальную команду getopts, которая сама просматривает специальные переменные и проверяет явлется ли параметр короткой опцией.
Напомним, что опцией называется параметр командной строки, начинающийся с символов '-' или '--'. Причем, если используется один знак минуса, то опция считается односимвольной или короткой, если же два знака минуса, то многосимвольной или длинной32.
Команда getopts вызывается следующим образом:
getopts строка_опций_поиска переменная
В строке_опций_поиска указываются односимвольные опции, которые должны быть «распознаны» getopts. Например, строка acdf говорит о том, что требуется найти какую либо из опций: -a, -c, -d или -f.
Алогритм работы команда getopts следующий.
Последовательно просматриваются специальные переменные $1, $2, $3…$#, начиная с номера, указанного в переменной OPTIND. При первоначальном запуске командной оболочки в OPTIND находится 133. Другими словами, если впервые вызвать команду getopts, то она начнет просмотр с переменной $1.
Если очередной параметр непустой и он не содержит опцию (не начинается с символа «-»), то getopts завершается с ненулевым кодом возврата.
32 33
Длинные опции в скрипте можно «распознавать» только через специальные переменные. Если потребуется заново провести проверку опций, то такое присвоение должен будет сделать пользователь.
50
Иначе считается, что найдена опция и производится сравнение следующего за тире символа с содержимым строки_опций_поиска.
Если найденная опция совпадает с одним из символов в строке_опций_поиска, то соответсвующий символ записывается в переменную.
Если совпадение необнаружено (т.е. в коммандной строке указана опция, которая отсуствует в строке_опций_поиска), на экран выводится сообщение об ошибке, переменной присваивается значение ''?''.
Если просматриваемый параметр больше не содержит символов, то номер следующего параметра записывается в переменную OPTIND (чтобы при следующем запуске команды продолжить просмотр параметров). В противном случае OPTIND остаѐтся без изменеения, а запоминается позиция внутри текущего просматриваемого параметра (чтобы в следующий раз продолжить просматривать этот параметр, считая его опцией и начиная со следующего символа).
В случае, если найдена «распознаваемая» или «нераспознаваемая» опция, код возврата getopts равен 0. В случае если просмотрены все параметры и больше опций нет, или очередной параметр не является опцией, то код возврата getopts отличен от 0.
Чтобы запретить выдачу сообщения об ошибке при нахождении опции, которая «нераспознаѐтся», необходимо либо переменной OPTERR присвоить 0, либо в строке_опций первым символом указать ―:‖ (двоеточие). В последнем случае getopts начинает работать в «тихом» (silent) режиме, и, в случае ошибки найденную «нераспознаваемую» опцию она помещает в переменную OPTARG, а в переменную помещает символ ―?‖.
Команда getopts позволяет «распознать» опции, для которых требуется дополнительный параметр. Для этого надо в строке опций после соответсвующего символа включить знак ‖:‖34. Например, в строке a:cdf: указывается, что опции –a и –f должны дополняться обязательным параметрами, например –a файл или –b время.
Если при «распознавании» найдена подобная опция, и за ней следует непустой параметр, то он помещается в переменную OPTARG, а сама опция помещается в переменную и getopts завершается.
Если опция найдена, но за ней нет параметра, то на экран выдаѐтся сообщение об ошибке, в переменную помещается символ «?» и getopts завершается. В «тихом» режиме при нахождении такой опции и осутсвия у неѐ параметра в переменную помещается символ ―:‖, а в переменную OPTARG помещается сама опция.
Например:
#!/bin/bash
while getopts ab:cde:f: OPTION ; do
34
этом в начале строки символ двоеточие может как присутствовать (чтобы перевести getopts в «тихий» режим), так и отсутствовать.
Обратите внимание, что в данном случае символ ―:‖ не является первым в строке, а следует за символом. При