Документация по ОС FreeBSD
Воскресенье, 09.11.2025, 07:18
Главная
Регистрация
Вход
Приветствую Вас
Гость
|
RSS
Меню сайта
Главная страница
Новости в мире Unix
NEW
Каталог файлов
NEW
Установка и настройка
Ports & Packages
cvs
Безопасность
Работа с железом
X Window
Multimedia
Man pages
Net
Apache
DNS
FTP
Mail
Samba
Squid
SSH
VPN
РРР
Shell
IPFW
Tips'n'tricks
RFC
Книги по FreeBSD
Темы экзамена BSDA
Гостевая книга
Форум на bsdportal.ru
Каталог сайтов
Самый свежий софт
Каталог ссылок
Категории каталога
Shell
[40]
Главная
»
Статьи
»
Программирование
»
Shell
Интерактивные интерфейсы пользователей
Командные интерпретаторы
Командный интерпретатор (по-другому - оболочка, shell) в операционных системах семейства UNIX предназначен для выполнения в основном следующих функций:
предоставление пользователю интерактивного интерфейса для общения с системой (другими словами: обработка и выполнение пользовательских команд)
выполнение файлов, содержащих команды интерпретатора (командные файлы);
В системах UNIX (и во FreeBSD естественно) имеются несколько различных командных интерпретаторов. Наиболее популярные из них:
sh - Bourne shell.
csh - С-shell.
ksh - Korn-shell.
bash - Bourne Again shell.
Как правило, все shell находятся в каталоге /bin. Но это не обязательно. Вы помните, что когда мы рассматривали вопросы установки packages, то установили интерпретатор bash в каталог /usr/local/bin. Все установленные в системе оболочки перечислены в файле /etc/shells.
Наберите команду cat /etc/shells, и вы увидите примерно следующее:
/bin/sh
/bin/csh
/usr/local/bin/bash
Если строка в файле, в котором записаны команды интерпретатора, начинается на # , то эта строка - комментарий. Это не относится к самой первой строке файла. Она должна содержать запись, типа #!/bin/sh. Это указывает, что для выполнения команд будет вызван интерпретатор /bin/sh.
Далее рассмотрим возможности и языки командных интерпретаторов.
Базовые возможности командных интерпретаторов
Для определенности, в данной главе будем рассматривать интерпретатор bash. Если вам больше нравится работать и программировать в другой оболочке, можете в принципе пропустить изучение этой главы курса. Но замечу, что базовые возможности разных оболочек примерно одинаковые.
Переменные и подстановка значений
Все переменные в языке shell - текстовые. Их имена должны начинаться с буквы и могут состоять из латинских букв, цифр и знака подчеркивания (_). Bash поддерживает как простые переменные, так и массивы. Для установки переменной используется оператор =:
Для простых переменных
<имя>=<значение>
Для массивов
<имя>[индекс]=<значение>, либо
<имя>=(<значение1> <значение2> ... <значениеN>), либо
<имя>=([индекс1]=<значение1> [индекс2]=<значение2> ... [индексN]=<значениеN>)
Чтобы воспользоваться значением переменной, надо перед ней поставить символ $. Можно также заключить переменную в фигурные скобки {}.
Например:
# hour=14
# echo $hour
14
# hourth=24
# echo $hourth
24
# echo ${hour}th
14th
Двойные кавычки ( " ), одиночные кавычки ( ' ), обратные кавычки ( ` )
Кавычки могут использоваться для создания строк. Например:
"Hello, world!"
'Good bye'
Кроме того, кавычки могут отменять действие следующих специальных символов:
` ~ ! # $ % ^ & * ( ) - + = | ; '" , . < > ?
Значения этих специальных символов в строках, заключенных в одиночные кавычки '<строка>' отменяются. В строках, заключенных в двойные кавычки "<строка>" также отменяются значения специальных символов, за исключением ! $ ` {. Обратная наклонная черта также отменяет действие специальных символов.
Не путайте одиночные и обратные кавычки. Пример:
# dat='date' (здесь стоят обратные кавычки)
# echo $dat
Mon Jun 05 14:17:20 2000
# dat='date' (здесь стоят одиночные кавычки)
# echo $dat
date
Конвейеры и списки
Несколько команд могут быть объединены с помощью символов канала |. В этом случае они образуют конвейер.
<команда1> | <команда2> | <команда3> ...
Символ канала | соединяет стандартный вывод команды <команда1> со стандартным вводом команды <команда2> и т.д.
Каждая команда выполняется в отдельном процессе, а состояние выхода последней команды будет являться состоянием выхода конвейера.
Примеры:
# ps -ax | more
# ls -l | grep "profile"
Кроме конвейеров, команды могут объединяться в списки. Даже сами конвейеры могут быть объединены в списки. Это делается с помощью команд ; && ||.
Команда ; просто последовательно выполняет оду команду или конвейер за другой (другим):
# make depend ; make ; make install
# cat /etc/passwd | grep root ; echo "User root"
Для того, чтобы управлять выполнением следующей команды в списке в зависимости от состояния выхода предыдущей, используются команды && (логическое И) и || (логическое ИЛИ).
Примеры:
# mkdir mydir && cd mydir
В этом случае команда cd mydir будет выполнена только в том случае, если успешно (состояние выхода равно 0) завершится команда mkdir mydir.
# cat /home/bob/.profile || echo "Нет файла .profile"
В этом случае либо на экран будет выведено содержимое файла /home/bob/.profile, либо сообщение о том, что такого файла нет.
Перенаправление ввода-вывода
Команды и списки могут содержать операторы < и > - перенаправления стандартного ввода и стандартного вывода соответственно.
Например:
# ps -ax > /etc/proc
выводит текущее состояние процессов не на экран, а в файл /etc/proc. Если к этому моменту такого файла не было, то он будет создан. Если он существовал, то его старое содержимое будет уничтожено новой информацией.
Для то, чтобы не уничтожать содержимое файла, а добавить новую информацию (в конец файла), нужно использовать оператор >>:
# ps -ax >> /etc/proc
Кроме того, существует стандартный вывод ошибок. Он имеет дескриптор 2. Т.е. если мы не хотим получать сообщения об ошибках на стандартный вывод, то можно использовать перенаправление таким образом:
# cat /etc/proc 2>err.log (ошибки, если возникнут, будут выведены в файл err.log) либо
# cat /etc/proc 2>/dev/null (ошибки будут выведены "никуда", их посмотреть будет невозможно).
Ввод перенаправляется аналогичным образом. Например, команда
# mail billgates@msn.com < /home/mail.txt
отправит содержимое файла /home/mail.txt по адресу billgates@msn.com.
Оператор << означает, что ввод для данной команды находится "ЗДЕСЬ". Пример:
# mail billgates@msn.com << end
Hello, Bill!
end
По этой команде в тело письма войдет все, что встретится до указанного нами ограничителя ввода end.
Управление ходом выполнения. Циклы
Управлять ходом выполнения сценария на языке bash можно, используя кострукцию операторов if-fi. Оператор if имеет вид:
if <условие 1>; then
<список операторов 1>
elif <условие 2>; then
<список операторов 2>
else
<список операторов 3>
fi
Работает эта конструкция так:
Если выполнено <условие 1>, то выполняется <список операторов 1>.
Если невыполнено <условие 1>, но выполнено <условие 2>, то выполняется <список операторов 2>.
Если невыполнено <условие 1> и невыполнено <условие 2>, то выполняется <список операторов 3>.
В конструкции if-fi операторы elif и else являются необязательными.
В качестве условия проверки может быть использована любая команда (или список команд). Тогда условие будет считаться выполненным, если команда (список команд) завершилась с кодом 0 (т.е. выполнилась нормально). Но на практике чаще используют команду test для проверки какого-либо выражения. Команда test записывается так:
test <выражение> или же [<выражение>]. Ниже приводится список опций, используемых при выполнении команды test.
-d file Истинно, если файл file существует и является директорией.
-e file Истинно, если файл file существует.
-f file Истинно, если файл file существует и является обычным файлом.
-k file Истинно, если файл file существует и для него установлен sticky-бит.
-L file Истинно, если файл file существует и является символической ссылкой.
-r file Истинно, если файл file существует и его можно читать.
-s file Истинно, если файл file существует и имеет ненулевой размер.
-t file Истинно, если файл file открыт на терминале.
-w file Истинно, если файл file существует и в него можно записывать.
-x file Истинно, если файл file существует и является выполняемым.
-O file Истинно, если файл file существует и принадлежит текущему пользователю.
file1 -nt file2 Истинно, если файл file1 создан (изменен) позднее, чем файл file2.
file1 -ot file2 Истинно, если файл file1 создан (изменен) раньше, чем файл file2.
-z <строка> Истинно, если длина строки <строка> равна нулю.
-n string Истинно, если длина строки <строка> не равна нулю.
string1 = string2 Истинно, если строки равны.
string1 != string2 Истинно, если строки не равны.
! <выражение> Истинно, если выражение ложно.
<выражение1> -a <выражение2> Истинно, если оба выражения истинны.
<выражение1> -o <выражение2> Истинно, если хотя бы одно из выражений истинно.
<число1> -eq <число2> Истинно, если число <число1> равно числу <число2>.
<число1> -ne <число2> Истинно, если число <число1> не равно числу <число2>.
<число1> -lt <число2> Истинно, если число <число1> меньше числа <число2>.
<число1> -le <число2> Истинно, если число <число1> меньше или равно числа <число2>.
<число1> -gt <число2> Истинно, если число <число1> больше числа <число2>.
<число1> -ge <число2> Истинно, если число <число1> больше или равно числа <число2>. Числами <число1> и <число2> могут быть положительные и отрицательные целые числа.
Пример:
if [ -x /usr/games/pool ] ; then
/usr/games/pool
else
echo "не могу запустить файл"
fi
Этот же пример можно записать по-другому:
[ -x /usr/games/pool ] && /usr/games/pool || echo "не могу запустить файл"
Циклы реализуются с помощью конструкций for, while.
Цикл for записывается так:
for <переменная> in <список>
do
<команды>
done
Пример 1:
for i in 1 2 3
do
echo $i
done
Пример 2:
for file in /etc/p*
do
echo $file
done
Этот цикл эквивалентен команде ls /etc/p*.
Цикл while имеет вид:
while <условие>
do
<команды>
done
Команды в теле цикла выполняются до тех пор, пока остается истинным <условие>.
Пример:
i=1
while [ $i -lt 5 ]
do
echo $i
i = $(($i+1))
# можно было бы написать i=`expr $i + 1`
done
Другим вариантом цикла while является until.
until <условие>
do
<команды>
done
В этом случае команды в теле цикла выполняются до тех пор, пока <условие> остается ЛОЖНЫМ.
i=1
until ! [ $i -lt 5 ]
do
echo $i
i='expr $i + 1'
done
Заметим, что по команде break можно выйти из тела цикла. Это справедливо и для цикла for и для while (until). Пример:
i=1
while [ $i -gt 0 ]
do
echo $i
i=`expr $i + 1`
if [ $i -eq 10 ] ; then
break
fi
done
Передача аргументов. Команда shift.
При запуске на выполнение, сценарию можно передать аргументы в командной строке. Например:
# /usr/games/pool file1.txt user1
Для того, чтобы можно было работать с переданными аргументами, существует девять переменных - $1, $2, ... , $9. Они позиционно соответствуют переданным аргументам. Т.е. в нашем примере $1 содержит строку "file.txt", а $2 содержит строку "user1". Кроме того, в переменной $# содержится количество переданных аргументов. В нашем случае -2.
Но что делать, если нужно передать, скажет, 15 аргументов ? Как получить доступ к аргументу с номером больше 9 ?
Для этой цели существует команда shift, которая просто осуществляет сдвиг аргументов на одну позицию "влево". Т.е. $1 получает значение $2, $2 - $3 и т.д. При этом значение, которое было в $1 до сдвига - теряется. При этом сдвиге так же уменьшается на 1 значение $#.
Рассмотрим это на примере. Создайте такой файл
#!/usr/local/bin/bash
i=1
while [ $# -eq 0 ]
do
echo "Аргумент $i - $1"
shift
i=`expr $i + 1`
done
Назовите его, например, my_shift.
Запустите его так:
# my_shift p1 p2 p3 p4
На экране вы увидете:
Аргумент 1 - p1
Аргумент 2 - p2
Аргумент 3 - p3
Аргумент 4 - p
Упражнения
1. Создайте в своей домашней директории несколько файлов с произвольным текстом.
2. Напишите скрипт, который бы принимал в качестве параметров имена этих файлов и добавлял их содержимое в файл, который передан первым в командной строке.
3. Запустите скрипт. Затем откройте файл-приемник, и проверьте, все ли правильно работает?
Ответ (пример скрипта):
#!/usr/local/bin/bash
if [ $# -gt 1 ] ; then
file=$1
i=$#
shift
while [ $# -eq 0 ]
do
cat $1 >> $file
shift
done
echo "Всего к файлу $file добавлено `expr $i - 1' файлов"
else
echo "Недостаточно аргументов"
fi
Категория:
Shell
| Добавил:
oleg
(08.12.2007)
Просмотров:
1621
| Рейтинг:
0.0
/
0
|
- Оценить -
Отлично
Хорошо
Неплохо
Плохо
Ужасно
Всего комментариев:
0
Добавлять комментарии могут только зарегистрированные пользователи.
[
Регистрация
|
Вход
]
Форма входа
Друзья сайта
Google+
Copyright MyCorp © 2025