Введение в Unix

         

Библиотеки


Как мы показали выше, на вход линкера могут подаваться не только файлы объектного кода, но и библиотечные файлы, которые оказываются очень удобным средством хранения объектных модулей, если их становится очень много.

Имя библиотечного файла обычно оканчивается на .a. Имеется команда ar (архив) для создания, пополнения и просмотра библиотечных файлов.

Пример создания библиотеки из трех объектных файлов:

$ ar rcv exam.a test.o check.o prove.o a - test.o a - check.o a - prove.o $

Здесь ключи команды ar означают:

r - заменить (replace) модули в библиотеке;

c - создать (create) библиотеку;

v - печатать включаемые модули (verbose).

Теперь мы можем распечатать содержимое библиотеки командой ar с ключом t (table of content):

$ ar t exam.a test.o check.o prove.o $

и ссылаться на библиотеку в командах вызова компиляторов или линкера, например:

$ ld -o test /lib/frt0.o exam.a -lF77

Следует помнить, что порядок размещения модулей в библиотеке существенен.

Например, если подпрограмма test вызывает подпрограмму check, то test.o должен предшествовать check.o в библиотеке. Для выявления и печати таких зависимостей предназначена команда lorder.



C-SHELL


Язык и интерпретатор языка C-Shell появился в версии системы UNIX Калифорнийского университета в Беркли UNIX BSD4.2 для VAX-11. Основные достоинства этой версии заключаются в добавлении в UNIX редакторов ex и vi, интерпретатора C-Shell, реализации языков ПАСКАЛЬ и ЛИСП, базы данных INGRES и других возможностей.



Чтение и запись файлов в буфере редактирования


Редактируемый файл находится в буфере редактирования. Чтение содержимого другого файла в буфер редактирования после указанной или текущей строки можно выполнить командой r, например:



0r preface.

Здесь содержимое файла чтения помещается в начале буфера редактирования (после несуществующей нулевой строки). В качестве файла чтения может быть файл стандартного вывода команды, например (пробел перед ! обязателен):

: r !date : 1, $p ---------- Fr Jan 12 09:33 PST 1986

Запись буфера редактирования или его части в указанный файл можно выполнить командой w, например:

: w newfile или

: w >> oldfile (добавление в существующий файл).

Попытка записи буфера в уже существующий файл сопровождается предупреждением и приглашением повторить команды с восклицательным знаком:

: w! oldfile

Если имя опущено, подразумевается редактируемый файл.

Пример записи части буфера редактирования:

: 1, 100w !lpr.

Здесь роль файла записи играет стандартный вывод команды (пробел перед знаком ! обязателен).



Демонтаж файловой системы


Если файловая система на съемном устройстве больше не используется, ее можно демонтировать командой umount, расположенной в каталоге /etc и имеющей один параметр:

umount <устройство>

Например, демонтиж файловой системы на гибком диске из предыдущего примера выполняется командой:

umount /dev/fl0

Результатом демонтажа является разрыв связи между корневым каталогом демонтируемой файловой системы и каталогом корневой файловой системы, в котором производился монтаж.

При выполнении команды демонтажа текущий каталог должен быть вне демонтируемой файловой системы, иначе будет выдано сообщение:

umount : device busy (устройство занято)

и команда не будет выполнена.



Диагностический вывод


Сообщения об ошибках, возникающих при выполнении команд, выводятся на диагностический вывод, по умолчанию это (как и стандартный вывод) - на экран. Диагностический вывод тоже может быть перенаправлен в любой файл. Для этого используется дескриптор файла (целое), который для стандартных файлов равен:

0 - Standard input; 1 - Stfndard output; 2 - Diagnostic output.

Пример:

$ cat somefile > outfile 2> errfile,

где знак > эквивалентен 1>.

Если вы хотите, чтобы сообщения об ошибках нигде не проявлялись, направьте их на /dev/null.

Если вы хотите направить ошибки туда же, куда вывод, надо набрать

Shell: $ cat somefile 1> outfile 2> &1 (ссылка на перенаправление)

Cshell: $ cat somefile >& outfile или

$ cat somefile |& lpr.



Добавление, изменение и уничтожение текста


Подвести курсор к нужной позиции и нажать одну из ниже указанных клавиш.

Уничтожение

x - уничтожить текущую букву (где курсор), текст сдвигается на ее место.

Изменение (замена):

r - замена текущей буквы;

rv - замена на v.

s - замена одной или нескольких букв текстом; например,

3stest - замена трех букв строкой 'test'.

Добавление:

i - вставить произвольный текст перед курсором. Конец ввода текста - клавиша Esc;

a - добавить произвольный текст после курсора. Конец ввода текста - клавиша Esc.



Файл начала сеанса (login - файл)


Независимо от версии Shell при входе в систему UNIX ищет файл начала сеанса с предопределенным именем, чтобы выполнить его как командный файл;

для UNIX версии 7 это: .profile; для C-Shell это: .login и/или .cshrc.

В этот файл обычно помещают команды:

установки характеристик терминала; оповещения типа who, date; установки каталогов поиска команд (обычно: /bin, /usr/bin); смена подсказки с $ на другой символ и т.д.



Файловые системы


Файловая система имеет иерархическую структуру каталогов и файлов, включая корневой каталог. Файловая система располагается на устройстве, которое является, обычно, магнитным диском того или иного типа. Если диск достаточно велик, он может быть разбит на несколько "логических" дисков; тогда на каждом логическом диске может быть размещена отдельная файловая система. Каждая файловая система, прежде чем стать доступной, должна быть смонтирована.

Количество файлов в файловой системе ограничено (65536 для UNIX, версия 7).

Каждая файловая система имеет четыре основные части:

загрузочный блок; это самый первый блок диска (блок 0), зарезервированный для системной загрузочной программы; супер-блок - это первый блок собственно файловой системы (блок 1); он содержит основные данные о файловой системе и ее размещении на диске, в том числе о списках свободных i-узлов и блоков; i-узлы - это последовательность блоков вслед за суперблоком; i-узел содержит ссылки на блоки; имеется ровно один i-узел для каждого каталога или файла в файловой системе; блоки - оставшееся пространство диска занимают блоки, которые содержат либо действительные данные каталогов и файлов (блоки данных), либо ссылки на блоки (косвенные блоки).

Суперблок содержит следующие данные:

размер дискового пространства, доступного файловой системе (в блоках); число блоков, зарегистрированных для i-узлов; имя файловой системы; имя тома; время последнего изменения; время последнего копирования (back up); ссылка на список свободных блоков; ссылка на список свободных i-узлов.




Структура файловой системы представлена на рис.13.1.



Рис.13.1.

Каждый файл (и каталог) в файловой системе представлен i-узлом, содержащим указатели на блоки, составляющие файл.

В i-узле содержится также информация о правах доступа к файлу, число ссылок на файл из каталогов и другие данные. Структура i-узла и блоков файла для UNIX, версия 7 показана на следующем рисунке. Каждый i-узел содержит 13 указателей. Первые 10 указателей непосредственно ссылаются на блоки данных файла. Поскольку блок содержит 512 байтов, то этого достаточно для обработки файлов до 512х10=5120 байтов.

Если длина файла больше, чем 5120 байта, используется 11-й указатель i-узла, который ссылается на косвенный блок из 128 ссылок на блоки данных. Использование косвенного блока позволяет увеличить длину файла до величины 512х(10+128)=70656 байтов. Если и этого недостаточно, то используется 12-й указатель i-узла, ссылающийся на дважды косвенный блок, содержащий 128 ссылок на косвенные блоки (рис.13.2). Тогда максимальный размер файла увеличивается до величины 512х(10+128+128**2)=8459264 байтов. Наконец, использование последнего, 13-го указателя на трижды косвенный блок из 128 ссылок на дважды косвенные блоки, дает предельную длину в файловой системе: 512х(10+128+128**2+128***3)=1082201088 байтов (см. рис. 13.2).

Другие версии системы UNIX могут отличаться количеством ссылок в i-узле, косвенных блоках и размером блока данных.

Когда система загружается, имеется только одна из файловых систем, называемая корневой. В ней находятся все важнейшие каталоги (/dev, /etc, /bin и т.п.). Все остальные файловые системы должны быть созданы и смонтированы.



Рис. 13.2.




Фильтры


Так называются команды, которые могут вводить со стандартного ввода и выводить на стандартный вывод. Большинство команд является фильтрами.

Есть исключения: ls не может работать со стандартным вводом. Или: lpr не может работать со стандартным выводом.



Формат команд


Команды разделяются либо концом строки, либо точкой с запятой:

$ who; date mary tty0 Feb 14 08 : 30 sun Feb 14 11 : 38 1985

Командная строка - последовательность слов, разделенных пробелами. Первое слово командной строки есть команда; остальные - параметры.

Типы параметров:

имя файла = идентификатор (использует символы a-z, A-Z, 0-9, _, ., -); опция (ключ) уточняет смысл команды; начинается обычно с минуса.

Например -al (может быть со знаком + или без знака); смысл опции зависит от команды; выражение - описывает обычно строку символов или является строкой.

Порядок параметров в команде:

command options expression filename(s)

Примеры команд:

rm old.news bod.news rm -fr goodies.c baddies.o grep -o "mary" people



Главные части UNIX


Ядро - управление основными ресурсами (процессор, оперативная память) и периферийными устройствами обмена и хранения данных (магнитные диски, магнитные ленты, принтеры, терминалы, линии связи и т.д.).

Файловая система (ФС) организует структуры данных на устройствах хранения.

Shell - командный интерпретатор: слушает ваш терминал и транслирует вашу команду в запрос к ядру и ФС.



Использование групп имен файлов


Кроме средств метасимволов для ссылки на множество файлов в C-Shell применяется средство группирования имен файлов для явного указания множества файлов в виде спискф имен файлов, заключенного в фигурные скобки.

Пример:

% cp /users/peter/animals/{cats, dogs, birds} или

% cp ~mary/animals/{cats, dogs, birds}.

Эта команда копирует множество из трех файлов с именами:

/users/peter/animals/cats /users/peter/animals/dogs /users/peter/animals/birds

В одной команде можно использовать более одной группы файлов, например:

% echo ls{/bin, /usr/ucb}{pi, is} ls /bin/pi /bin/is /usr/ucb/pi /usr/ucb/is



Использование метасимволов *, ?, []


Метасимволы служат для подстановки любых строк и символов. В именах файлов в командах языка заданий Shell:

* - представляет произвольную строку (возможно, пустую);

? - любой одиночный знак;

[C1 - C2] - любая литера из диапазона C1 - C2 (в стандарте ASCII).

Примеры:

$ ls c? c1 c2 c3 cs cz

$ ls c* c1 c12 c2 c23 c3 cs cs1 cxy cz

$ ls ?1* c1 c12

$ ls *1* c1 c12 cs1

$ ls c [12 x y z] c1 c2 cz

ls c [12 x y z *] c1 c2 c12 c25 cz cxy



Использование временных файлов в каталоге /tmp


Это специальный каталог, в котором все файлы доступны на запись всем пользователям.

Если некоторая процедура, создающая временный файл, используется несколькими пользователями, то необходимо обеспечить уникальность имен создаваемых файлов. Стандартный прием - имя временного файла $0$$, где $0 - имя процедуры, а $$ - стандартная переменная, равная уникальному идентификационному номеру процесса, выполняющего текущую команду.

Хотя администратор периодически удаляет временные файлы в /tmp, хорошей практикой является их явное удаление после использования.



Исправление ошибок при наборе текста команды


Исправление последней буквы путем набора:

<backspace> или

^H или

# (диез)

Исправление последней строки путем набора:

^X или

^V или

@



Изменение и повторное исполнение предыдущих команд


Для исполнения частично измененных предыдущих команд используется средство подстановки :s (substitution) части текста (похожее на аналогичное средство в редакторе ex).

Пусть имеется следующий буфер истории:

% history 1 ls -l 2 mail 3 cd /users/peter/shels 4 cd /users/peter/shells 5 history 6 cd /users/peter/shells 7 ls -l 8 mv /users/wowa/spacewar.c space.c 9 pr space.c | lpr 10 history

Используем средство подстановки для изменения и исполнения команды mv:

% !8 : s /spacewar/empire/ mv /users/wowa/empire.c space.c.



Изменение рабочего каталога


Изменение рабочего каталога производится командой (cd - change directory).

$ cd /etc $ ls -l - печать команд администратора

$ cd /usr $ ls -l bin - редко используемые команды

$ cd - без параметров - возврат к собственному (home) каталогу.



Языки программирования в UNIX


С, ПАСКАЛЬ, ФОРТРАН используются чаще всего; СНОБОЛ, БЭЙСИК и многие другие также доступны во многих реализациях UNIX; интерактивные арифметические калькуляторы.

Компиляторы языков программирования - наиболее машинно-зависимые части реализаций UNIX, так как генерация кодов на каждом компьютере своя.



Электронная почта (mail)


Электронная почта - это средство, позволяющее пользователям посылать друг другу сообщения, которые складываются в почтовые ящики, реализованные внутри системы.

Когда вы входите в систему, вас извещают о наличии для вас почты, например:

login: mary password: ... you have mail $

В отличие от write в системе mail о приходе для вас почты вас известят, когда вы закончите текущую работу, печатая сообщение:

you have mail (для вас есть почта).

Для получения почты введите команду mail без параметров:

$ mail Form peter Wed Jun 9 17:58:23 1991 Завтра в 16:30 можно поиграть в теннис. Где встретимся? ?

Подсказка (?) означает, что система mail ждет указания о том, что делать с почтой: печатать, сохранить, уничтожить или выйти из команды mail. Введя знак вопроса, вы получите меню возможных действий:

?? q quit - закончить;

x exit without changing mail - выйти без изменения почты;

p print - печатать;

s [file] save - сохранить в файле;

w [file] same without header - то же без заголовка;

- print previous - печатать предыдущее;

d delete - уничтожить;

+ next (no delete) - следующее (не уничтожать);

m user mail to user - переправить другому пользователю;

!cmd execute cmd - выполнить команду;

?

Кроме этих десяти действий вы можете также ввести Ctrl-D (то же, что и q) или нажать клавишу возврата каретки.

При сохранении почты в файле на экране высвечивается следующее письмо, если оно есть:

? s from_peter From peter ........... ?

Можно переслать данное письмо другим пользователям.

Например:




? m mary boris george ?

Для посылки почты введите команду mail с параметром - именем пользователя и введите текст письма, заканчивая его знаком конца файла (Ctrl-D).

Например:

$ mail peter Извини, я не смогу играть завтра. Мне надо получить талоны на сахар и табак. ^D $

Посылка ответа может быть произведена при просмотре почты.

Например:

?! mail peter Извини, я ..... .......... ^D ! ?

Для просмотра почты из файла введите команду mail с ключом -f:

$ mail -f from_peter

Для выхода из системы mail наберите q.

Например:

? q you have mail $.

Работа с почтой закончена.


КАТАЛОГИ И ФАЙЛЫ


При регистрации пользователя ему назначается администратором собственный каталог пользователя (Home directory).



Команда test


Не является частью Shell, но применяется внутри Shell-процедур.

Имеется три типа проверок:

оценка числовых значений; оценка типа файла; оценка строк.

Для каждого типа свои примитивы (операции op).

Для чисел синтаксис такой:

N op M,

где N, M - числа или числовые переменные;

op принимает значения: -eq, -ne, gt, -lt, -ge, -le (с обычным смыслом, как, например, в ФОРТРАН).

Для файла синтаксис такой:

op filename,

где op принимает значения:

-s (файл существует и не пуст);

-f (файл, а не каталог);

-d (файл-директория (каталог);

-w (файл для записи);

-r (файл для чтения).

Для строк синтаксис такой:

S op R , где S, R - строки или строковые переменные или

op1 S

op принимает значения:

= (эквивалентность);

!= (не эквивалентность);

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 ... .



Командные файлы (скрипты) в C-Shell


Командный файл (скрипт) - это файл, состоящий из команд, выполняемых группой. Примеры скриптов - файлы .login, .cshrc, .logout. Прежде чем писать свой скрипт, проверьте UNIX Reference используемой Вами версии UNIX, нет ли там команды, уже решающей вашу задачу.

Первый способ выполнения скрипта - ввести команду:

% csh sname arg1 arg2 ...,

где sname - имя скрипта; arg1, arg2, ... - аргументы скрипта.

Аргументы скрипта автоматически помещаются во встроенные переменные $argv[1], $argv[2] и так далее.

Кроме того, аргументы доступны по ссылкам $n, где n - целое, равное позиции аргумента; $0 означает sname. Различие между $argv[n] и $n заключается в том, что первая ссылка дает ошибку при выходе значения n за допустимые пределы, а вторая - нет.

Второй способ выполнения скрипта в C-Shell - обеспечить его выполнимость (командой chmod) и позаботиться о том, чтобы он начинался с символа # (диез); в противном случае скрипт будет выполняться обычным Shell.

Пример:

% chmod a+x sname % sname arg1, arg2, ...

При выполнеии скрипта производится подстановка значений переменных, ссылки на которые указывает знак $. Переменная должна обладать значением в момент ссылки на нее, иначе возникает ошибка.

Узнать, присвоено ли значение переменной, можно с помощью выражения $?<имя> (1 - присвоено, 0 - нет), а количество компонентов значения дает выражение $#<имя>.

На компоненты значения можно ссылаться выражением $<имя>[n], где n - номер компоненты. Компоненты значения разделяются пробелами, а многокомпонентное значение заключается в скобки.

Пример:




% set sum1 = (a b c) % echo $?sum1 1 % echo $#sum1 3 % echo $sum1[2] b % unset sum1 % echo $?sum1 0.

Другими полезными подстановками, начинающимися знаком $, являются:

$* - эквивалентно $argv>;

$$ - номер процесса; поскольку он уникален в системе, его удобно использовать для генерации уникального имени временного файла;

$< - заменяется строкой последующего ввода со стандартного ввода (клавиатура терминала), что очень полезно при написании интерактивных скриптов.

Пример:

echo "yes or no?" set a = ($<)

На экране высветится запрос (yes or no?), затем будет прочитан ответ и присвоен переменной a.




Команды сравнения файлов (diff, cmp, comm)


В процессе разработки программного обеспечения возникает необходимость сравнения версий файла на разных этапах его разработки. Узнать, чем версии отличаются друг от друга, удобно командой diff, которая показывает разницу (difference) двух файлов; сравнение файлов осуществляется по строкам (записям). В результате выполнения команды печатаются строки измененные (c), уничтоженные (d) и добавленные (a) во втором файле-аргументе по сравнению с первым.

Пример:

$ cat people Mary Clark 101 Sally Smith 113 Jane Buily 121 $ cat people.new Mary Clark 101 Sally White 113 James Walker 112 $ diff people people.new 2 c 2 <Sally Smith 113 - - - - >Sally White 113 3 d 2 <Jane Baily 121 3 a 3 >James Walker 112

Знаки < и > означают удаление и добавление строк; команда показывает также номера строк, в которых найдены отличия.

Если строки отличаются только числом разделяющих слова пробелов, также отличия можно подавить ключом -b (blank).

Например:

$ diff -b oldfile newfile $.

Другая возможность быстрого сравнения файлов - команда cmp (compare), реализованная на основе побайтового (побуквенного) сравнения двух файлов.

Пример:

$ cmp people people.new people, people.new differ: char 17, line 2

В качестве результата печатается число отличающихся байтов (букв) и строк (линий).

Ключ -l (long) позволяет распечатать разницу файлов в виде байтов (адрес и отличающиеся значения).

Например:

$ cmp people people, new 26 123 127 27 155 150 30 150 155 - - - - - - - - 197 60 61 198 60 61




Если файлы сильно отличаются друг от друга, сравнить их эффективнее командой comm (common), которая показывает, что в двух файлах одинаковое общее.

Например:

$ cat people Mary Clark 101 Sally Smith 113 Jane Baily 121 $ cat people.new Mary Clark 101 Sally White 113 James Walker 112 $ comm people people.new Mary Clark Sally Smith Sally White Jane Baily James Walker

Результат команды comm печатается в три колонки: строки первого файла, отсутствующие во втором: строки второго файла, отсутствующие в первом, и строки, общие для двух файлов.

Можно подавить печать одного или двух столбцов, указывая его номер в виде ключа, например (печать только третьего столбца):

$ comm -12 people people.new Mary Clark $




Комментарии в процедурах


Они начинаются с двоеточия :, которое считается нуль-командой, а текст комментария - ее аргументом. Чтобы Shell не интерпретировал метасимволы ($, * и т.д.), рекомендуется заключать текст комментария в одиночные кавычки.

В некоторых вариантах ОС UNIX примечание начинается со знака #.



Контроль использования дисковой памяти


Регулярное выполнение команды du (disk usage) позволяет выявить пользователей, захвативших слишком много дисковой памяти. Команда печатает число блоков, занятых каждым файлом и каталогом в дереве, указанном именем каталога - параметром команды. Например:

du /

Будут выведены объемы всех файлов и каталогов.

Использование команды find помогает выявить долго неиспользуемые файлы большого объема. Например:

find / -m time+90 -a time+90 -print

Будут показаны все файлы, к которым не обращались ни по записи, ни по чтению последние 90 дней.

С помощью команды find администратор может также найти файлы, представляющие опасность для операционной системы или бесполезно занимающие пространство на диске, даже если место расположения этих файлов в иерархии каталогов неизвестно.

Например:

find / -name danger -print

Поиск производится начиная с корневого каталога /. Ключ -name указывает последующее имя файла danger, а ключ -print предписывает вывод полного имени файла danger на экран.

Команда df (disk free) показывает число свободных блоков всех или указанной параметром файловой системы.

Следует учитывать также, что учетные файлы (типа /usr/lib/cronlog) могут расти неограниченно и требуют периодической чистки или сброса.



Копирование файлов командой cp


Это простейший способ создать файл:

$ cp /etc/motd message.

Полагая, что текущий каталог progs/c, мы создали файл progs/c/message.

Можно копировать файл в текущий или другой каталог, не меняя его имени:

$ cp /etc/motd progs/c.

Будет создан файл progs/c/motd.

Если текущий каталог progs/c, того же эффекта достигает команда:

$ cp /ets/motd . (с точкой в качестве параметра).

Если второй аргумент каталог, то в качестве первого можно указывать несколько файлов:

$ cp /etc/motd /usr/include/stdio.h progs/c

Режим доступа файла - копии совпадает с режимом доступа исходного файла (см. раздел 4.16).



Коррекция предыдущей команды


Имеются различные средства для повторного исполнения предыдущих команд, возможно, с изменением части повторяемой команды.

Для коррекции непосредственно предыдущей команды есть следующие средства редактирования.

Пример:

% cd /users/peter/shels /users/peter/shels: No such file or directory.

Допущена ошибка: shels вместо shells. Она исправляется следующим образом:

%^shels^shells^ cd/users/peter/shells %

Исправленная команда заносится в буфер истории:

% history 1 ls -l 2 mail 3 history 4 cd /users/peter/shels 5 cd /users/peter/shells 6 history

Чтобы редактировать произвольную предыдущую команду, можно воспользоваться командой s (substitution) подстановки (см. раздел 8.6).



Линкер


На практике программы создаются из множества раздельно транслируемых модулей, каждый из которых занимает отдельный файл. Результатом компиляции каждого модуля является файл объектного (перемещяемого) кода, имя которого получается заменой .c (или .f, .p и т.д.) на .c. Затем все объектные файлы объединяются в единую программу, помещаемую в файл исполняемого кода, посредством линкера. Линкер может вызываться как независимой командой ld, так и автоматически при выполнении команд вызова компилятора cc, fc, pc и т.д. В последнем случае эти команды могут иметь несколько параметров-файлов, имена которых могут оканчиваться не только на .c, .f, .p, ..., но и на .o. Файлы исходного текста компилируются, а затем все файлы объектного кода, как полученные в результате компиляции, так и параметры команды вызова компилятора, передаются линкеру. Результатом по-прежнему является файл с именем по умолчанию a.out, если вы не указали явно другое имя.

При этом, как правило, объектные файлы уничтожаются. Чтобы сохранить их, можно подавить автоматический вызов линкера ключом -c (только компиляция) в команде вызова компилятора.

Пример:

$ fc -c test.f check prove.f $ ld /lib/frt0.o *.o -lF77 $ ls a.out check.f check.o prove.f prove.o test.f test.o $

Здесь добавлены файл /lib/frt0.o стартового модуля для программы на ФОРТРАНе (для C /lib/crt0.o) и библиотека - lF77 подпрограмм для ФОРТРАНа (для C - lc); могут быть добавлены и другие библиотеки. Обозначение -lx является сокращением для /lib/libx.a для любого x. Следует заметить, что библиотеки указываются последними (не являются ключами команды ld). При автоматическом вызове линкера стартовый модуль и ряд библиотек вызываются по умолчанию. Чтобы их увидеть, следует применить ключ -v в командах вызова компилятора.



Литература


Bell System Technical Journal, 1957, vol.6, pp. 1977-2200. MacGilton H., Morgan R. Introducing the UNIX System. - McGrow-Hill, 1983, 556 pp. Кристиан К. Операционная система UNIX. - М., Финансы и статистика, 1985, 320 стр. Топхейм Д., Хай Ван Чыонг. Юникс и Ксеникс. - М., Мир, 1988, 392 стр. Баурн С. Операционная система UNIX. - М., Мир, 1986, 464 стр. Aho A.V., Kernighan B.W., Weinberger P.J. Awk - A Pattern Scanning and Text Processing Language (2d Edition). - Bell Labs, Murray Hill, N.J. Feldman S.I. Make - a program for maintaining computer programs. - Bell Labs, Murray Hill, N.J. (а также в журнале Software - Practice and Experience, vol.9). Свиридов С.В. "Программирование в операционной системе UNIX". - М., "Компьютер Инвайтс", 1991, 110 стр. Lesk M.E., Schmidt E. Lex - a lexical analyzer generator. - Bell Labs, Murray Hill, N.J. Johnson S.C. Yacc - Yet Another Compiler-Compiler. - Bell Labs, Murray Hill, N.J. Тихомиров В.П., Давидов М.И. Операционная система ДЕМОС: инструментальные средства программирования. - М., Финансы и статистика, 1988. Стариков Ю.А. Администратор системы UNIX. М., Интерквадро, 1989. Дегтярев Е.К. Тенденции развития вычислительной техники. - М., "Компьютер Инвайтс", 1991, 96 стр. Interactive UNIX System V/386 Release 3.2 Operating System Guide. - Interactive System Corporation, Santa Monica, CA, 1990.



Механизм истории


Встроенный механизм истории интерпретатора C-Shell хранит заданное число последних введенных вами команд. Число хранимых команд равно значению предопределенной переменной history, которую вы можете установить в файле .cshrc командой set:

% set history = 15

(в отличие от Shell при установке переменной требуется слово set).

Чтобы посмотреть хранимые команды, надо распечатать на экране буфер механизма истории командой history, например:

% history 1 ls -l 2 mail 3 history %

Механизм истории обеспечивает возможность вызвать любую из хранимых команд, печатая восклицательный знак и номер команды, например:

% ! 1 ls -l . . . . %



Механизм переименования


Этот механизм, называемый alias, позволяет дать дополнительные (обычно короткие) имена часто используемым (обычно длинным) командам.

Пример:

% alias cdm1 cd /users/sys/doce/mans/man/man1 % alias cdm2 cd /users/sys/doce/mans/man/man2 % alias cdm3 cd /users/sys/doce/mans/man/man3

Чтобы изменить текущий каталог, например, на ...man2, достаточно ввести соответствующую команду по ее дополнительному имени:

% cdm2 % pwd /users/sys/doce/mans/man/man2.

Те же переименования можно выполнить короче с использованием ссылки !$ на последнее слово команды:

% alias cdm cd /users/sys/docs/mans/man/man \!$ % cdm 3 % pwd / users/sys/docs/mans/man3.

Обратный слэш перед восклицательным знаком исключает действие восклицательного знака как специального символа.

Отмена переименования производится командой unalias, например:

% unalias cdm.



Метасимволы в C-Shell


Метасимволами называются символы, имеющие специальное значение для интерпретатора.

В C-Shell имеются следующие метасимволы:

синтаксические; именования файлов; кавычки; ввода - вывода; подстановки; прочие.

Многие из них сходны по функциям с аналогичными функциями метасимволов обычного Shell.

Синтаксические метасимволы:

; - разделяет команды, которые будут выполнены последовательно;

- - разделяет команды, соединенные каналом, так что стандартный вывод левой является стандартным вводом правой;

-& - аналогично -, однако диагностический вывод тоже направляется на ввод следующей команды;

( ) - объединяют команды, разделенные предыдущими знаками, в единое целое для использования в последовательности или с каналом;

& - предписывает выполнение команды на заднем плане параллельно со следующей командой, например:

cat letter>/dev/lp &

-- - аналогичен знаку -, однако правая команда выполняется, только если левая завершилась аварийно;

&& - аналогичен знаку -, однако правая выполняется, только если левая завершилась нормально.

Метасимволы именования файлов:

? - любой символ в имени файла. Например, файлы fa.o, fb.o, fc.o могут быть напечатаны одной командой:

$ cat f?.o > total.o

* - любая строка в имени файла. Например, удаление всех файлов, имена которых начинаются с old:

% rm old*

[] - любая одна буква из указанного в квадратных скобках диапазона. Например:

% ls f.[a - z] - печать всех файлов типа f.x, где x - буква из диапазона a - z;

{} - аналогичны квадратным скобкам >[], однако вместо диапазона указано множество букв. Например, печать файлов list, last, lost:




% ls l{iao}st;

~ - полное имя рабочего каталога пользователя (см.выше);

/ - разделяет имена каталогов и файла в полном имени файла или каталога.

Метасимволы - кавычки:

\ - отменяет мета-значение следующего за ним одного метасимвола. Например:

% ls \* * not found (в то время как % ls * - печать всех файлов текущего каталога);

' ' - отменяет мета-значения группы символов. Пример:

% set string = 'ws - l $dir / $file'

" " - аналогичны одиночным кавычкам, однако подстановка значений переменных и команд выполняется. Пример:

% echo "$dir is not a directory."

Метасимволы ввода - вывода:

< - перенаправление ввода;

> - перенаправление вывода (если переменная noclobber установлена, перезапись существующего файла вывода не происходит);

>& - перенаправление диагностического вывода;

>! - перенаправление вывода (с обязательной перезаписью существующего файла вывода);

>&! - аналогично >! для диагностического вывода;

>> - аналогично >, однако вывод добавляется в конец существующего файла вывода; если файл не существует и переменная noclobber установлена, возникает ошибка;

>>& - аналогично >&, однако вывод добавляется в конец файла вывода;

>>! - аналогично >>, однако, если файл вывода не существует, он создается (ошибки не возникает);

>>&! - комбинация >>& и >>!.

Метасимволы подстановки:

$ - указывает подстановку значения переменной, например:

% set M1 = /usr/man/man3 % cd $M1

! - указывает подстановку команды из буфера истории;

: - указывает подстановку строк в команде из буфера истории;

? - используется в специальных случаях подстановок команд из буфера истории.

Прочие метасимволы:

# (диез) - указывает комментарий C-Shell; начинает имена временных файлов; должен быть первым символом командного файла в C-Shell;

% - указывает номер процесса, например:

kill %1.




Начало и конец сеанса работ


Каждый пользователь имеет:

имя пользователя (для установления взаимодействия пользователей и начисления расходов); пароль пользователя (для контроля входа в систему и защиты своих данных).

Пользователи могут быть объединены в группы (для работы над проектами и т.п.) для разделения общих ресурсов, тогда еще есть имя группы пользователей.

Один пользователь,называемый superuser является администратором системы (его имя - root). В частности, он "заводит" (регистрирует) всех прочих пользователей.

Можно сменить свой пароль в любое время:

login : peter password: . . . . $ passwd Changing password for peter Old password: . . . New password: *** Retype new password: *** $ ^D (Ctrl-D) (выход из сеанса)

login:

где $ - подсказка системы (может быть изменена на любой символ или строку).



Некоторые команды C-Shell


В добавление к командам языка Shell в C-Shell появился ряд полезных команд. Рассмотрим некоторые из них. Команда ls с ключом -F позволяет получить листинг каталога с указанием знаком * исполнимых файлов и знаком / каталогов.

Пример:

% ls -F mail help lint1* tabset/

Команда head, симметричная команде tail, позволяет посмотреть на экране заданное количество первых строк файла (по умолчанию 10 строк), например:

% head -2 people Mary Clark 101 Sally Smith 113

Листание файла на экране позволяет осуществить команда more, например:

% more somefile <первая страница файла> - - More - - (3 %) %

Процент в скобках указывает уже просмотренную часть файла. Для последовательного постраничного просмотра нажмите клавишу пробела, для построчного - клавишу возврата каретки.

Можно задать начало просмотра со строки с заданным номером или заданным значением. Примеры:

% more +194 somefile . . . . . % more +'more then' somefile

В общем случае значение задается регулярным выражением, как в ed или grep (см. раздел 10.5).

Команда apropos позволяет найти разделы руководств, касающиеся заданного ключевого слова.

Пример:

% apropos sort ddsort (3/21/80) - sort DDBS files

look (1) - find lines in a sorted list

. . . . . . . . . . . . . . . tsort (1) - topological sort

% man look <руководство по look (1)>

Просмотреть заголовки руководств можно командой whatis, например:

% whatis mv ln cp cp (1) - copy

ln (1) - make links

mv (1) - move or rename files

Команда whereis позволяет найти специальные файлы, связанные с указанной командой (опция -m находит файл руководства, опция -b - файл кода команды).

Пример:

% wheris -m rm rm: /usr/man/man1/rm.1 % wheris -b rm rm: /bin/rm

Команда strings позволяет просмотреть в любом (в том числе выполнимом) файле все строки (в коде ASCII).



Некоторые простые команды


Дата:

$ date Sun Fed 14 11:38 1985 $

Узнать всех пользователей (активных):

$ who mary tty0 Feb 14 08 : 30 peter tty5 Feb 14 08 : 32 . . . $

Вариант:

$ who am i mary tty 0 Feb 14 08 : 30



Непечатные символы в именах файлов


Символы со знаком Ctrl: ^A, ^[ (escape) и т.п., полученные одновременным нажатием клавиши Ctrl и указанной после символа ^ клавиши, не видны на печати. Команда ls может показать файл, а rm и другие команды могут не принять имя этого файла (т.к. часть символов не видна). Выход - в использовании * в именах (или использование режима rm -i):

$ ls arron circle square triangle $ rm square rm: square non-existent (если вместо q в имени ^q)

$ ls s* square $ rm s* $

Теперь файл удален.



Обработка команд в режиме заднего плана (background)


Обычно команды выполняются в режиме переднего плана (foreground), т.е. "пока вы ждете". Однако, если во время выполнения некоторой команды вы хотите выполнять другие команды, то эту (первую) команду можно выполнить в режиме background:

$ nroff doc & 2042 $.

Об этом говорит завершающий знак &.

Система UNIX создает процесс, который выполняется независимо от командного интерпретатора. Ответ 2042 - это идентификатор этого процесса (PID). Лучше перенаправлять стандартный вывод процесса заднего плана в файл (из-за опасности совмещения вывода "переднего" и "заднего" плана на экране).

$ nroff doc > doc.format & 2042 $ или

$ nroff doc | lpr & 2042 $

Чтобы выяснить состояние процесса заднего плана, надо использовать команду ps (process status):

$ ps PID TTY TIME CMD 2036 02 0:05 sh (login - процесс терм.2)

2042 02 0:02 nroff doc (background)

2043 02 0:01 ps (cat pS)

2050 08 0:03 sh (login - процесс терм.8).

Это показывает, что nroff еще не закончилась. Ключи l и a в команде ps могут дать больше информации об активных процессах:

-l - информация о родителе, адрес, приоритет и т.д.

-a - о всех процессах системы.



Обработка прерываний в процедурах


Если при выполнении процедуры получен сигнал прерывания (от клавиши BREAK или DEL, например), то все созданные временные файлы останутся неудаленными (пока это не сделает администратор) ввиду немедленного прекращения процесса.

Лучшим решением является обработка прерываний внутри процедуры оператором trap:

Синтаксис: trap 'command arguments' signals...

Кавычки формируют первый аргумент из нескольких команд, разделенных точкой с запятой. Они будут выполнены, если возникнет прерывание, указанное аргументами signals (целые):

2 - когда вы прерываете процесс;

1 - если вы "зависли" (отключены от системы)

и др.

Пример (развитие предыдущего):

case $1 in ..... *) trap 'rm /tmp/*; exit' 2 1 (удаление временных файлов)

if test -s $1 .............. rm /tmp/*

Лучше было бы:

trap 'rm /tmp/* > /dev/null; exit' 2 1

так как прерывание может случиться до того, как файл /tmp/$0$$ создан и аварийное сообщение об этом случае перенаправляется на null-устройство.



Обработка прерываний в скриптах


Если ваш скрипт создает временные файлы, вы можете захотеть уничтожить их, даже если прерывание скрипта не позволит вам выполнить скрипт до конца (предполагается, что в конце скрипта временные файлы всегда уничтожаются).

Для этого вам нужно в начале скрипта выполнить команду onintr label, где label - произвольная метка, начиная с которой в вашем скрипте стоят команды, которые будут выполнены, если произойдет прерывание (так как в случае прерывания

C-Shell автоматически выполнит команду goto label, где label - метка из команды onintr).

При этом вы можете предусмотреть среди выполняемых в случае прерывания команд в качестве последней команду exit 1, чтобы обеспечить ненулевое значение переменной $status, свидетельствующей о неблагополучном завершении скрипта.



Обработка текстовых файлов командой awk


Awk - утилита, подобная grep. Однако, кроме поиска по образцу, она позволяет проверять отношения между полями строк (записей) и выполнять некоторые действия над строками (генерировать отчеты). Название не является акронимом, оно образовано первыми буквами фамилий авторов (A.V.Aho, P.Y.Weinberger, B.W.Kernighan).

Задание поиска-действия следует синтаксису:

/<образец>/{<действие>}

И образец, и действие могут отсутствовать. Найденные по образцу строки при отсутствии заданного действия выводятся в стандартный вывод (на экран).

Образец задается регулярным выражением, как и в grep. Если образец отсутствует, обрабатываются все строки.

Рассмотрим примеры действий, которые можно выполнить командой awk.

Перестановка полей строки выполняется с помощью ссылки на поле $n, где n - номер поля.

Например:

$ cat people Mary Clark 101 Henry Morgan 112 Bill Williams 100 $ awk '{print $2 "," $1 "^I" $3}' people Clark, Mary 101 Morgan, Henry 112 Williams, Bill 100

где ^ (Ctrl-I) - знак табуляции для подвода каретки к очередной позиции табуляции (для выравнивания третьего поля).

Действия для awk могут быть заданы в файле.

Например:

$ cat swap {print $2 "," $1 "^I" $3} $ awk -f swap people

Awk имеет встроенные образцы и переменные. Образцы BEGIN и END означают начало и конец файла соответственно. Переменная NR (Number of Records) означает число записей (строк) в файле, NF - число полей в записи. Можно использовать переменные, объявленные пользователем. Пример, подсчитывающий среднее значение третьего поля файла tennis (программа действий для awk - в файле average):




$ cat > average {total = total + $3} END {print "Average value is", total/NR} ^D $ awk - f average tennis Average value is 8.9 $

Образец поиска в awk может содержать условные выражения. Пример, в котором в файле tennis пишутся все записи, значение третьего поля в которых не меньше 10:

$ awk '$3 >= 10 {print $0}'tennis Steve Daniel 11 Hank Parker 18 Jack Austen 14 $

Знак $0 (доллар-ноль) есть ссылка на всю запись (строку).

В общем случае выражение для условия подчиняется синтаксису, близкому к синтаксису выражений в языке C. Кроме того, в команде awk допустимо указывать отрезок образцов. Пример выборки всех записей, сделанных с 1976 до 1978 г.:

$ sort -n -o chard.s chard $ awk '/1976/, /1978/ {if($2 < 8.00 print $0}' chard.s 1976 7.50 Chateau 1977 7.75 Chateau 1978 5.99 Charles

Как видно из примера, в программах действий для awk можно использовать управляющие структуры с синтаксисом, близким к языку C.

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

$ awk {for (i = NF; i > 0; --i) print $i} f1,

где NF - число полей в записи.

Полное описание средств awk можно найти в статье авторов [6].


Оценка состояния файла


Выражение, возвращающее значение, зависящее от состояния файла, используется в условных операторах (см.ниже). Значение равно единице (1), если выражение истинно, и ноль (0), если оно ложно или файл не существует.

Синтаксис выражения:

-op <имя файла>,

где op принимает значения:

d - является ли файл каталогом?

e - файл существует?

f - является ли файл простым файлом?

o - это мой собственный файл?

r - имею ли я право чтения файла?

w - имею ли я право записи файла?

x - могу ли я выполнить файл?

z - файл пуст (длина ноль байтов)?

Пример:

if (-d $dir) then echo "**** $dir is a directory"



Операции над словами и строками


Уничтожение слова (слов):

подвести курсор к началу слова и нажать:

dw - (delete word);

2dw - 2 слова;

ndw - n слов (n - число).

Изменение слова:

подвести курсор к началу слова и печатать:

cw < слово > Esc 2cw <два слова> Esc и т.д.

Уничтожение части строки

d$ - от текущего символа до конца строки (текущий символ исчезает - то же делает D);

d^ - от начала строки до текущего символа (текущий символ остается).

Замена части строки (аналогична)

c$ или C <текст замены> Esc - замена конца строки (от курсора) текст замены может быть из нескольких строк.

c^ <текст замены> Esc - замена начала строки (до курсора, не включая его).

Уничтожение целой строки

dd - уничтожение одной строки;

10dd - уничтожение 10 строк.

Замена целой строки

cc <текст> Esc - замена одной строки;

5cc < текст > Esc - замена пяти строк.

Создание новой строки

о - пустая строка после текущей строки;

O - пустая строка перед текущей строкой.

Ввод до и после текущей строки:

^i или I - до;

$a или A - после.



Оператор цикла 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 в списке значений.

Пример:

for file in *people (для всех имен, кончающихся на people)

do ... done.

Если in опущено, то по умолчанию в качестве списка значений берется список аргументов процедуры, в которой содержится цикл, а если цикл не в процедуре, то - список параметров командной строки (то есть в качестве процедуры выступает команда).

Пример:

for file do ... done

Для вызова makelist adminpeople hardpeople softpeople будет сделано то же самое.



Оператор цикла 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

Исполняется аналогично предыдущему.



Оператор цикла 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 sort + 1 - 2 $1 | tr -d ... (процедуры) fi shift (* перенумеровать аргументы *) done

Процедуры выполняются над всеми аргументами.



Оператор foreach


Оператор цикла foreach имеет синтаксис:

foreach <индекс> (<список значений индекса через пробелы>) <команда 1> <команда 2> .......... end.

Все команды выполняются для каждого значения индекса из списка значений.

Внутри цикла можно использовать команду break для прекращения выполнения цикла и команду continue для преждевременного прекращения одной текущей итерации.

При выходе из цикла индекс имеет значение последнего элемента из списка значений.



Оператор goto


Допускаются метки операторов и оператор goto.

Например:

loop: <команда 1> <команда 2> .......... goto loop



Оператор if-then-endif


Условный оператор имеет синтаксис:

if (<выражение>) then <команда 1> <команда 2> .......... else <команда A> <команда Б> .......... endif

Если альтернатива else пуста (команды А, Б, ... отсутствуют), else можно опустить. Реализация C-Shell требует, чтобы if и then были обязательно на одной строке.

Допустимы вложенные условные операторы, например:

if (<выражение 1>) then <команда 1> .......... else if (выражение 2> then <команда А> .......... else <команда X> .......... endif endif

Если в первой альтернативе только одна команда, допускается следующий синтаксис:

if (<выражение>) <команда 1> или

if (выражение>\ <команда>

где символ \ должен предшествовать символу перевода каретки.



Оператор switch


Оператор выбора имеет синтаксис:

switch (<переменная>) case <значение 1>: <команды> ........ breaksw case <значение 2>: <команды> ........ breaksw ........ case <значение n>: <команды> ........ breaksw default: <команды> ........ breaksw endsw

В отличие от аналогичного оператора в языке C здесь используется специальный оператор breaksw для выхода из альтернативы.

Выполнение осуществляется следующим образом: значение переменной сравнивается последовательно со значениями 1, 2, ..., n, и выполняются команды первой из альтернатив, для которых значения совпали. Если таких значений не оказалось, выполняются команды из альтернативы по умолчанию (default).



Оператор выбора case


Синтаксис:

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.