ОС Томск
.pdfНезависимо от версии Shell при входе в систему UNIX ищет файл начала сеанса с предопределенным именем, чтобы выполнить его как командный файл;
-для UNIX версии 7 это: .profile;
-для C-Shell это: .login и/или .cshrc.
Вэтот файл обычно помещают команды:
-установки характеристик терминала;
-оповещения типа who, date;
-установки каталогов поиска команд (обычно: /bin, /usr/bin);
-смена подсказки с $ на другой символ и т.д.
Процедура языка Shell
Это командный файл. Два способа его вызова на выполнение:
1.$ sh dothat (где dothat — некоторый командный файл);
2.$ chmod 755 dothat (сделать его выполнимым, т.е. -rwxr-xr-x) $ dothat.
Следует знать порядок поиска каталогов команд (по
умолчанию):
-текущий;
-системный /bin;
-системный /usr/bin.
Следовательно, если имя вашего командного файла дублирует имя команды в системных каталогах, последняя станет недоступной (если только не набирать ее полного имени).
Переменные Shell
В языке Shell версии 7 определение переменной содержит имя и значение: var = value.
Доступ к переменной — по имени со знаком $ спереди: fruit = apple (определение);
echo $fruit (доступ); apple (результат echo).
Таким образом, переменная — это строка. Возможна конкатенация строк:
$ fruit = apple
80
$ fruit = pine$fruit $ echo $fruit pineapple
$ fruite = apple
$ wine = ${fruite}jack $ echo $wine applejack
$
Другие способы установки значения переменной — ввод из файла или вывод из команды, а также присваивание значений переменной — параметру цикла for из списка значений, заданного явно или по умолчанию.
Переменная может быть:
-Частью полного имени файла: $d/filename, где $d — переменная (например, d = /usr/bin).
-Частью команды:
$ S = "sort + 2n + 1 - 2" (наличие пробелов требует кавычек "")
$ $S tennis/lpr
$ $S basketball/lpr $ $S pingpong/lpr
$
Однако внутри значения для команды не могут быть символы |, >, <, & (обозначающие канал, перенаправления и фоновый режим).
Предопределенные переменные Shell
Некоторые из них можно только читать. Наиболее употребительные:
HOME — "домашний" каталог пользователя; служит аргументом по умолчанию для cd;
PATH — множество каталогов, в которых UNIX ищет команды;
PS1 — первичная подсказка (строка) системы (для v.7 - $).
81
Изменение PS1 (подсказки) обычно делается в login-
файле, например: |
|
|
|
|
PS1 = ? |
|
|
или |
PS1 = "? " (с пробелом, что удобнее). |
||
Изменение PATH: |
|
|
|
$ echo $PATH |
- посмотреть; |
||
:/bin:/usr/bin |
- значение PATH; |
||
$ cd |
|
- "домой"; |
|
$ mkdir bin |
- новый каталог; |
||
$ echo $HOME |
|
- посмотреть; |
|
/users/maryann |
- текущий каталог; |
||
$ PATH = :$HOME/bin:$PATH |
- изменение PATH; |
||
$ echo $PATH |
- посмотреть; |
||
:/users/maryann/bin:/bin:/usr/bin |
- новое значение |
||
PATH. |
|
|
|
Установка переменной Shell выводом из команды
Пример 1:
$ now = `date` (где `` - обратные кавычки) $ echo $now
Sun Feb 14 12:00:01 PST 1985
$
Пример 2: (получение значения переменной из файла): $ menu = `cat food`
$ echo $menu
apples cheddar chardonnay (символы возврата каретки заменяются на пробелы).
Переменные Shell — аргументы процедур
Это особый тип переменных, именуемых цифрами. Пример:
$ dothis grapes apples pears (процедура).
Тогда позиционные параметры (аргументы) этой команды доступны по именам:
$1 = `grapes`
82
$2 = `apples` $3 = `pears`
и т.д. до $9. Однако есть команда shift, которая сдвигает имена на остальные аргументы, если их больше 9 (окно шириной 9).
Другой способ получить все аргументы (даже если их больше 9): $*, что эквивалентно $1$2 ...
Количество аргументов присваивается другой переменной: $#(диез).
Наконец, имя процедуры - это $0; переменная $0 не учитывается при подсчете $#.
Структурные операторы Shell
Оператор цикла for
Пусть имеется командный файл makelist (процедура) $ cat makelist
sort +1 -2 people | tr -d -9 | pr -h Distribution | lpr.
Если вместо одного файла people имеется несколько,
например: adminpeople, hardpeople, softpeople,..., то необходимо повторить выполнение процедуры с различными файлами. Это возможно с помощью for — оператора. Синтаксис:
for <переменная> in <список значений> do <список команд>
done
Ключевые слова for, do, done пишутся с начала строки. Пример (изменим процедуру makelist):
for file in adminpeople, hardpeople, softpeople do
Sort +1 -2 $file | tr ... | lpr
done.
Можно использовать метасимволы Shell в списке значений.
Пример:
83
for file in *people (для всех имен, кончающихся на
people)
do
...
done.
Если in опущено, то по умолчанию в качестве списка значений берется список аргументов процедуры, в которой содержится цикл, а если цикл не в процедуре, то — список параметров командной строки (то есть в качестве процедуры выступает команда).
Пример: for file
do
...
done
Для вызова makelist adminpeople hardpeople softpeople
будет сделано то же самое.
Условный оператор if
Используем имена переменных, представляющие значения параметров процедуры:
sort +1 -2 $1 | tr ... | lpr
Пример неверного вызова:
makelist (без параметров), где $1 неопределен. Исправить ошибку можно, проверяя количество аргументов – значение переменной $# посредством if - оператора.
Пример: (измененной процедуры makelist): if test $# -eq 0
then
echo "You must give a filename" exit 1
else
sort +1 -2 $1 | tr ... | lpr
fi
84
Здесь test и exit - команды проверки и выхода. Таким образом, синтаксис оператора if:
if <если эта команда выполняется успешно, то>;
then <выполнить все следующие команды до else или, если его нет, до fi>;
[else <иначе выполнить следующие команды до fi>]
Ключевые слова if, then, else и fi пишутся с начала строки. Успешное выполнение процедуры означает, что она возвращает значение true = 0 (zero) (неуспех - возвращаемое
значение не равно 0).
Оператор exit 1 задает возвращаемое значение 1 для неудачного выполнения makelist и завершает процедуру.
Возможны вложенные if. Для else if есть сокращение elif, которое одновременно сокращает fi.
Команда test
Не является частью Shell, но применяется внутри Shellпроцедур.
Имеется три типа проверок:
-оценка числовых значений;
-оценка типа файла;
-оценка строк.
Для каждого типа свои примитивы (операции op).
1.Для чисел синтаксис такой: N op M, где N, M - числа или числовые переменные;
op принимает значения: -eq, -ne, gt, -lt, -ge, -le.
2.Для файла синтаксис такой: op filename, где op принимает значения:
--s (файл существует и не пуст);
--f (файл, а не каталог);
--d (файл-директория (каталог);
--w (файл для записи);
--r (файл для чтения).
Для строк синтаксис такой: S op R, где S, R - строки или строковые переменные или op1 S, где op принимает значения:
-= (эквивалентность);
85
-!= (не эквивалентность); op1 принимает значения:
--z (строка нулевой длины);
--n (не нулевая длина строки).
Наконец, несколько проверок разных типов могут быть объединены логическими операциями -a (AND) и -o (OR).
Примеры:
$ if test -w $2 -a -r S1
>then cat $1 >> $2
>else echo "cannot append"
>fi
$
В некоторых вариантах ОС UNIX вместо команды test используются квадратные скобки, т.е. if [...] вместо if test ... .
Оператор цикла while Синтаксис:
while <команда> do
<команды> done
Если "команда" выполняется успешно, то выполнить "команды", завершаемые ключевым словом done.
Пример:
if test $# -eq 0 then
echo "Usage: $0 file ..." > &2 exit
fi
while test $# -gt 0 do
if test -s $1 then
echo "no file $1" > &2
else
86
sort + 1 - 2 $1 | tr -d ... (процедуры)
fi
shift (* перенумеровать аргументы *)
done
Процедуры выполняются над всеми аргументами.
Оператор цикла until
Инвертирует условие повторения по сравнению с while Синтаксис:
until <команда> do
<команды> done
Пока "команда" не выполнится успешно, выполнять команды, завершаемые словом done.
Пример:
if test S# -eq 0 then
echo "Usage $0 file..." > &2 exit
fi
until test S# -eq 0 do
if test -s $1 then
echo "no file $1" > &2
else
sort +1 -2 $1 | tr -d ... (процедура)
fi
shift (сдвиг аргументов) done
Исполняется аналогично предыдущему.
Оператор выбора case Синтаксис:
87
case <string> in
string1) <если string = string1, то выполнить все следующие команды до ;; > ;;
string2) <если string = string2, то выполнить все следующие команды до ;; > ;;
string3) ... и т.д. ...
esac
Пример:
Пусть процедура имеет опцию -t, которая может быть подана
как первый параметр:
.................
together = no case $1 in
-t) |
together = yes |
|
shift ;; |
-?) |
echo "$0: no option $1" |
|
exit ;; |
esac
if test $together = yes then
sort ...
fi
где ? - метасимвол (если -?, т.е. "другая" опция, отличная от -t, то ошибка). Можно употреблять все метасимволы языка Shell, включая ?, *, [-]. Легко добавить (в примере) другие опции, просто расширяя case.
Использование временных файлов в каталоге /tmp
Это специальный каталог, в котором все файлы доступны на запись всем пользователям.
Если некоторая процедура, создающая временный файл, используется несколькими пользователями, то необходимо обеспечить уникальность имен создаваемых файлов. Стандартный прием – имя временного файла $0$$, где $0 - имя
88
процедуры, а $$ - стандартная переменная, равная уникальному идентификационному номеру процесса, выполняющего текущую команду.
Хотя администратор периодически удаляет временные файлы в /tmp, хорошей практикой является их явное удаление после использования.
Комментарии в процедурах
Они начинаются с двоеточия : , которое считается нулькомандой, а текст комментария - ее аргументом. Чтобы Shell не интерпретировал метасимволы ($, * и т.д.), рекомендуется заключать текст комментария в одиночные кавычки.
В некоторых вариантах ОС UNIX примечание начинается со знака #.
Пример процедуры
:'Эта процедура работает с файлами, содержащими
имена'
: 'и номера телефонов,' :'сортирует их вместе или порознь и печатает результат
на'
:'экране или на принтере' :'Ключи процедуры:'
:'-t (together) - слить и сортировать все файлы вместе' :'-p (printer) - печатать файлы на принтере'
if test $# - eq 0 then
echo "Usage: $ 0 file ... " > & 2 exit
fi
together = no print = no
while test $# -gt 0 do case $1 in
-t) together = yes shift ;;
-p) print = yes
89
