UNИX, весна 2008, 07 лекция (от 26 марта)

Материал из eSyr's wiki.

(Различия между версиями)
Перейти к: навигация, поиск
(Новая: Зачем нужны хардлинки? 1. Если есть программа, которая меняет своё поведение в зависимости от имени. Дл...)
 
(14 промежуточных версий не показаны.)
Строка 1: Строка 1:
-
Зачем нужны хардлинки?
+
[[Изображение:Uneex 08 03 26 01.jpg|thumb|240px]]
-
1. Если есть программа, которая меняет своё поведение в зависимости от имени. Для чего это нужно --- экономить байты
+
-
2. Когда имена лежат в разных каталогах, при чём, если такой способ использования, что пользователеь файлом попользовался и удалил
+
-
/* 3. Если нужно условно говоря написать конфиг, но специфичность его такова, что это специфичной функции типа маллок, и там может быть например, что забивать --- это симлинк */
+
-
== Два маленьких дополнения: софтлинки и OCL ==
+
'''Диктофонная запись:''' http://esyr.org/lections/audio/uneex_2008_summer/uneex_08_03_26.ogg
-
Жёсткие ссылки это хороший инструмент, но у которого есть два крупных недостатка:
+
= Еще о файлах и правах доступа =
-
* Вы не можете по определнию ж. ссылки создать ссылку на файл в другой ФС
+
== Жесткие ссылки ==
-
* Вы не можете создать жёсткую ссылку на каталог. Почему этоог сделать нельзя: предположим, у нас есть директория д1, а в нём д2, ссылающийся на ту же иноду, что и д1. Фактически, для одного объекта есть два имени: d1 и d1/d2. Можете представить себе реурсивный разбор: d1, потом d2, потом d2 и так, пока память не кончится. И поскольку вы не можете их отличить, то так делать нельзя.
+
-
Для решения этих проблем есть другой объект ФС: симв. ссылка ls -l обозн. l). Это файл, в котором хранится "настоящее" имя файла. Там хранится некая подстановка: выкидывает имя файла и подставляет его содержимое: например, если файл .../f1 сожержит d2/f3/, то будет .../d2/f3/. Симв. ссылки придуманы для того, чтобы обойти оба ограничения. Здесь любая программа в точности знает, что это симв. ссылка и траверсить её не будет.
+
Жетские ссылки (hardlink) -- это записи имён в каталогах (мы помним, что каталог это тот же файл, только своего типа), которые ссылаются на один и тот же индексный дескриптор (inode) этой файловой системы. Все жесткие ссылки на файл выступают равноправными именами его. файл существует на диске до тех пор, пока не будет удалено последнее из его имён. Число имен файла отображается выводе команды ls -l, в первой позиции для каждого файла.
-
Про конфиг: вы можете исп. конфиг-файлы, и можно создать симв. ссылку неизвестно на что. Вообще, то, что там есть, необязано существовать, но написать туда можно что угодно, и тогда для чтения надо не три файловых операции, а одна.
+
Зачем нужны жесткие ссылки?
 +
# Если есть программа, которая меняет своё поведение в зависимости от имени (она его сможет прочитать в argv[0]). Тогда можно снабдить её несколькими именами. Для чего это нужно --- экономить байты
 +
# Когда один и тот же файл лежит в разных каталогах. Тогда какой-то пользователь может каким-то файлом попользоваться и удалить, а у других он останется.
 +
<!-- 3. Если нужно условно говоря написать конфиг, но специфичность его такова, что это специфичной функции типа маллок, и там может быть например, что забивать --- это симлинк -->
-
=== АЦЛ ===
+
== Cимвольные ссылки ==
-
В юнихе исп. субъект-субъектная модель со множеством субъектов. Все объекты в ФС нумеруются по одному и тому же списку --- мн. субъектов. Субъекты бывают как уникальные --- пользователи, так и группы. И все субъекты вычисл. по простой арифметике. Всё это в общем довольно естественный задания прав доступа, тем не менее, существует неск. юзкейзов, когда субъект-субъектная модель работает неудобно. Например, если какому-то пользозвателю надо что-то запретить, то для этого надо созд. спец. группу, перетаскивать всех туда... Есть теоретическое обосн., почему эта модель неполная: когда однй надо дать только на запись, другой --- только на чтение. Чтобы только наметить, в какой парадигме она решается: есть не только уник. идент. пользователя, но и объекта. Чтобы облегчить/усложнить чебе жизнь, вводим группы объектов, и вот эти уник. и групповые идент. объектов к польз. отн. не имеют, там своя классиф. И на осн. этих 4 таблиц: список польз., групп, объектов, групп объектов, можно изобразить права, кто что с чем может делать. Тогда эта задача вполне легко решается. Это стандартизовано такой объектный способ доступа стандартизован в POSIX, называется ACL, и List выдаёт нам отличие: в субъект-субъектной инф-ции очень малый оверхед --- 9 битов плюс ещё немного суммарно в районе 60 бит), а втой моделти, что описано сейчас, может их быть мноог. Чтобы это обойти,водружаются групповые политики, правила наследования .... с одной стороны, это сильно загромождает понимание, кто что может, особенно введение наследования. Не смотря на то,что оно подджерживается большинством Линух-систем, пользоваться ей надо в искл. случае.
+
Жёсткие ссылки это хороший инструмент, но у него есть два крупных недостатка:
 +
* Вы не можете по определению создать жесткую ссылку на файл, расположенный в другой файловой системе (т.к. жесткая ссылка влкючает в себя inode, а их нумерация в каждой ФС своя)
 +
* Вы не можете создать жёсткую ссылку на каталог, это запрещено. Почему это решили запретить: предположим, у нас есть каталог d1, а в нём d2, ссылающийся на тот же inode, что и d1. Фактически, для одного объекта есть два имени: d1 и d1/d2. Можете представить себе рекурсивный обход каталогов: d1, потом d2, потом снова d2, потом снова d2, и так, пока память не кончится. И поскольку вы никогда не сможете отличить, какое из имён главное, а какое дополнительное, то так делать запрещено.
-
Соотв. команды называются setfacl/getfacl.
+
Для решения этих проблем есть другой объект ФС: символьная ссылка (такие файлы в выводе ls -l обозначаются символом l в первой позиции). Это файл, в котором хранится путь к некоторому другому файлу. При обращении к файлу-ссылке имя самого этого файла заменяется на его содержимое: например, если файл-ссылка .../f1 содержит значение d2/f3/, то обращение фактически будет к .../d2/f3/. И, наконец, если значение файла-ссылки начинается на /, то на его содержимое будет заменён весь этот путь.
 +
 
 +
Символьные ссылки придуманы для того, чтобы обойти оба ограничения жёстких ссылок. Здесь любая программа точно сможет отличить символьную ссылку, и большинство вменяемых программ (по умолчанию) по ним не ходят.
 +
 
 +
Может возникнуть такая специфическая задача. Может потребоваться отладочный конфиг-файлы, например, для функции malloc. В trusted системах бывает нужно, чтобы malloc всегда возвращал память чистую, заполненную нулями. Это можно настроить в некотором конфиг-файле и попросить malloc при каждом вызове читать настройки из этого файла. Однако же, действие это состоит из трех операций (открыть файл, прочитать настройки, закрыть файл), это много, особенно если вызовы malloc происходят часто. Известно, что символьной ссылке в качестве значения можно прописать все что угодно, это необязательно должен быть реально существующий файл. Так вот, можно прописать в неё нужную нам конфигурационную строчку, и тогда для чтения её потребуется не три файловых операции, а одна: readlink().
 +
 
 +
== Access Control List (ACL) ==
 +
 
 +
В UNIX используется субъект-субъектная модель разграничения доступа со множественным субъектом. Все объекты в файловой системе нумеруются по одному и тому же списку --- множественных субъектов. Субъекты бывают как уникальные --- пользователи, так и множественные, т.е. группы. И все права субъектов вычисляются по простой арифметике (3x3, было на прошлой лекции). Всё это в общем довольно естественный способ задания прав доступа, тем не менее, существует несколько use case'ов (случаев использования), когда субъект-субъектная модель работает неудобно.
 +
 
 +
Например, если какому-то конкретному пользователю надо что-то конкретное запретить, например, доступ к некоторому файлу. Это можно реализовать и в модели: для этого надо создать специальную группу, занести туда всех пользователей, кроме провинившегося, и назначить этому файлу, например, такие права: rwxrwx---
 +
 
 +
Но есть теоретическое обоснование, почему эта модель неполная: когда для некоторого файла одной группе надо дать права только на запись, другой --- только на чтение, этого в ней сделать никак нельзя. Наметим, в какой парадигме она решается: нужна уникальная идентификация не только пользователя, но и объекта. Чтобы облегчить/усложнить себе жизнь, можем еще ввести множественные объекты, т.е. группы объектов. Эти уникальные и групповые идентификаторы объектов к пользователям отношения не имеют. И на основе этих 4 таблиц: пользователей, групп пользователей, объектов, групп объектов, можно изобразить права, кто что с чем может делать. Тогда эта задача вполне легко решается.
 +
 
 +
Такой объектный способ доступа стандартизован в POSIX, называется ACL (access control list), и слово list выдаёт нам его особенность. В субъект-субъектной модели вместе с каждым объектом нужно хранить фиксированное, малое количество информации касательно прав доступа --- 9 битов плюс ещё идентификаторы пользователя и группы, суммарно в районе 70 бит), а в этой модели, информации может быть столько, что на сами объекты на диске места останется с гулькин нос.
 +
 
 +
Чтобы это обойти, в ACL вводятся разного рода механизмы: групповые политики, правила наследования, и т.п. .... Но это сильно загромождает понимание того, кто что в итоге может, особенно введение наследования. Не смотря на то,что оно поддерживается большинством Linux-систем, пользоваться ей надо в исключительных случаях. Был случай, когда школьники пришли на олимпиаду по программированию, а им всем оказался разрешен доступ на сетевой диск на запись, именно из-за какой-то ошибки в ACL.
 +
 
 +
Соответствующие команды (если нужный пакет установлен) называются getfacl/setfacl.
= Краткий обзор шелла как ЯП =
= Краткий обзор шелла как ЯП =
-
Нынче немодно говорить, что шелл --- полный Яп, а бат --- неполный. Говорят,что цмд полный.
+
Нынче немодно говорить, что шелл --- полный ЯП, а BAT --- неполный. Говорят, что CMD полный.
-
Поговорим про то, что такое скрипт --- сценарий с т. з. юних систем. Уже говорилось, что в юних, а в след за ним и в линух свойство файла быть запускаемым опр. специальным режимом доступа. При этом этот файл внутри себя может быть как бинарником, но файд может быть и текстовым. Для вып. этого файла запускается интерпретатор, который его интерп. По умолчанию этот файл --- шелл. Именно поэтому, когда говорят скрипт, имеют в виду шеллскрипт. Это искл, которому доверять не надо. В линух принято след. правило: сценарий --- фалй, который начинается с #!<интерпретатор>/ "nj gthdfz cnhjrf afqkf? yfghbvth #!/bin/sh. Эта строчка позволяет системе решить,что этот файл должен исполняться соотв. интерпретатором. Запустили prog 1 2 3, а у prog написано #!/bin/sh, то запустится на самом деле /bin/sh prog 1 2 3, причём шелл делает так, что список аргументов начинается с prog. На самом деле, скрипты пишутся на чём угодно: perl, python, ..., лишь бы интерпретатор проигнорирова шабанг. Отсюда замечательное свойство --- во многих языках строка с решётки --- комментарий. Ещё одно свойство --- сказав chmod +x, сделал из скрипта программу.
+
Поговорим про то, что такое скрипт --- сценарий с т. з. юних систем. Уже говорилось, что в юних, а в след за ним и в линух свойство файла быть запускаемым опр. специальным режимом доступа (использование). При этом этот файл внутри себя может быть как бинарником, а может быть и текстовым. Для вып. этого файла запускается интерпретатор, который его интерп. По умолчанию этот интерпретатор --- шелл. Именно поэтому, когда говорят скрипт, имеют в виду шеллскрипт. Это искл, которому доверять не надо. В линух принято след. правило: сценарий --- файл, который начинается с #!<интерпретатор>/ "то первая строка файла, например #!/bin/sh. Эта строчка позволяет системе решить,что этот файл должен исполняться соотв. интерпретатором. Запустили prog 1 2 3, а у prog написано #!/bin/sh, то запустится на самом деле /bin/sh prog 1 2 3, причём шелл делает так, что список аргументов начинается с prog. На самом деле, скрипты пишутся на чём угодно: perl, python, ..., лишь бы интерпретатор проигнорировал sha-bang (эту самую первую строчку). Отсюда замечательное свойство --- во многих языках строка с решётки --- комментарий. Ещё одно свойство --- сказав chmod +x, сделал из скрипта программу.
-
Практически на тех же правах, что и перем. окруж, определяется куча пареметров разных, в том числе для работы ... . Переменная $0 будет соотв. нулевому аргументу, $1 --- первому, и так далее до 9. Ещё етьс такая команда shift, которая без параметров производит сдвижку на 1 параметр вправо. Зачем это нужно: у вас там флаги, потом имена файлов. Вы флаги прошифтили, а дальше только имена файлов. $* --- строка целиком. $@ тоже содержит строку целиком, заведена она для того, чтобы операцию подстановки внутри кавычек. Разница при квотировании: "$*" --- одна большая строка ("$1 $2 $3"), а результатом "$@" будут отдельные параметры ("$1" "$2" "$3"). Если посмотреть на $@ то кажется, что это специфическая, контексно-зависимая штука, потоому что работает иначе, но пользоваться этим удобно. Что ещё есть: $# --- количество параметров командной строки.
+
Практически на тех же правах, что и перем. окруж, определяется куча пареметров разных, в том числе для работы ... . Переменная $0 будет соотв. нулевому аргументу, $1 --- первому, и так далее до 9. Ещё есть такая команда shift, которая без параметров производит сдвижку на 1 параметр вправо (2 в 1, 3 в 2, ..., 10 в 9). Зачем это нужно: у вас там флаги, потом имена файлов. Вы флаги прошифтили, а дальше только имена файлов, можно обрабатывать их в цикле. $* --- строка целиком. $@ тоже содержит строку целиком, заведена она для того, чтобы операцию подстановки внутри кавычек. Разница при квотировании: "$*" --- одна большая строка ("$1 $2 $3"), а результатом "$@" будут отдельные параметры ("$1" "$2" "$3"). Если посмотреть на $@ то кажется, что это специфическая, контексно-зависимая штука, потому что работает иначе, но пользоваться этим удобно. Что ещё есть: $# --- количество параметров командной строки.
* $_ --- последняя введённая польз. строка
* $_ --- последняя введённая польз. строка
Строка 41: Строка 60:
{cmd1; cmd2;} > f
{cmd1; cmd2;} > f
-
Про скобки: можно рассматривать их как операторные скобки. Одно из свойств фигурных скобок состоит в том, что ввлод-вывод объекдиняется. Если для того, чтобы для того, чтобы запустить эти команды, не надо запусктаь отдельного шелла, то они выполн. в текущем. Но если нужно, то запускаются отдельно: echo ... | read A, то ... .Если же записать круглые скобки: (cmd1; cmd2) > f, то обязательно запускается отдельный шелл. Этод удобно для того, чтобы понаопределять переменных, а потом всё забыть
+
Про скобки: можно рассматривать их как операторные скобки. Одно из свойств фигурных скобок состоит в том, что ввод-вывод объединяется. Если для того, чтобы запустить эти команды, не надо запусктаь отдельного шелла, то они выполн. в текущем. Но если нужно, то запускаются отдельно: echo ... | read A, то ... .Если же записать круглые скобки: (cmd1; cmd2) > f, то обязательно запускается отдельный шелл. Этод удобно для того, чтобы понаопределять переменных, а потом всё забыть
== Условный оператор ==
== Условный оператор ==
Строка 65: Строка 84:
...
...
esac
esac
-
На самом деле жутко удобная штука, потому что используются wildcards.
+
При всём некрасивом синтаксисе, на самом деле, жутко удобная штука, потому что используются wildcards, т.е. производится сопоставление шаблонов.
== Функции ==
== Функции ==
Строка 76: Строка 95:
В шелле есть команда trap, которая позволяет перехватывать сигналы, посылаемые процессы. Синтаксис:
В шелле есть команда trap, которая позволяет перехватывать сигналы, посылаемые процессы. Синтаксис:
trap <функция> сигнал
trap <функция> сигнал
-
B njulf j,hf,jnxbr --- не система, а функция. Никаких специфич. парам. там нет. Единственное, среди списка сигналов есть специальное слово EXIT, которое словом не является, а является флагом выхода из скрипта, функция ыполняется после завершения скрипта. Для чего это нужно --- для того, чтобы удалять файлы, созданные mktemp, например. Деаетсяэто следующим образом: пишется функция, которая создаёт временный файл и добавляет его в переменную, написать onexit() { trap - EXIt; cleanfile}
+
B тогда обработчик --- не система, а функция. Никаких специфич. парам. там нет. Единственное, среди списка сигналов есть специальное слово EXIT, которое словом не является, а является флагом выхода из скрипта, функция ыполняется после завершения скрипта. Для чего это нужно --- для того, чтобы удалять файлы, созданные mktemp, например. Делается это следующим образом: пишется функция, которая создаёт временный файл и добавляет его в переменную, написать
 +
onexit() { trap - EXIT; cleanfile}
 +
 
 +
Первым делом в ней нужно отключить обработку EXIT, иначе shell будет бесконечно этот обработчик вызывать.
 +
 
 +
ДЗ: привести пример, что можно, или доказать, что нельзя с использованием сигналов сделать очередь для диспетчеризации процессов на разные процессоры...
-
ДЗ: доказать или опровергнуть, что с использованием сигналов можно сделать очередь.
+
{{UNИX, весна 2008}}
 +
{{Lection-stub}}

Текущая версия

Диктофонная запись: http://esyr.org/lections/audio/uneex_2008_summer/uneex_08_03_26.ogg

Содержание

[править] Еще о файлах и правах доступа

[править] Жесткие ссылки

Жетские ссылки (hardlink) -- это записи имён в каталогах (мы помним, что каталог это тот же файл, только своего типа), которые ссылаются на один и тот же индексный дескриптор (inode) этой файловой системы. Все жесткие ссылки на файл выступают равноправными именами его. файл существует на диске до тех пор, пока не будет удалено последнее из его имён. Число имен файла отображается выводе команды ls -l, в первой позиции для каждого файла.

Зачем нужны жесткие ссылки?

  1. Если есть программа, которая меняет своё поведение в зависимости от имени (она его сможет прочитать в argv[0]). Тогда можно снабдить её несколькими именами. Для чего это нужно --- экономить байты
  2. Когда один и тот же файл лежит в разных каталогах. Тогда какой-то пользователь может каким-то файлом попользоваться и удалить, а у других он останется.

[править] Cимвольные ссылки

Жёсткие ссылки это хороший инструмент, но у него есть два крупных недостатка:

  • Вы не можете по определению создать жесткую ссылку на файл, расположенный в другой файловой системе (т.к. жесткая ссылка влкючает в себя inode, а их нумерация в каждой ФС своя)
  • Вы не можете создать жёсткую ссылку на каталог, это запрещено. Почему это решили запретить: предположим, у нас есть каталог d1, а в нём d2, ссылающийся на тот же inode, что и d1. Фактически, для одного объекта есть два имени: d1 и d1/d2. Можете представить себе рекурсивный обход каталогов: d1, потом d2, потом снова d2, потом снова d2, и так, пока память не кончится. И поскольку вы никогда не сможете отличить, какое из имён главное, а какое дополнительное, то так делать запрещено.

Для решения этих проблем есть другой объект ФС: символьная ссылка (такие файлы в выводе ls -l обозначаются символом l в первой позиции). Это файл, в котором хранится путь к некоторому другому файлу. При обращении к файлу-ссылке имя самого этого файла заменяется на его содержимое: например, если файл-ссылка .../f1 содержит значение d2/f3/, то обращение фактически будет к .../d2/f3/. И, наконец, если значение файла-ссылки начинается на /, то на его содержимое будет заменён весь этот путь.

Символьные ссылки придуманы для того, чтобы обойти оба ограничения жёстких ссылок. Здесь любая программа точно сможет отличить символьную ссылку, и большинство вменяемых программ (по умолчанию) по ним не ходят.

Может возникнуть такая специфическая задача. Может потребоваться отладочный конфиг-файлы, например, для функции malloc. В trusted системах бывает нужно, чтобы malloc всегда возвращал память чистую, заполненную нулями. Это можно настроить в некотором конфиг-файле и попросить malloc при каждом вызове читать настройки из этого файла. Однако же, действие это состоит из трех операций (открыть файл, прочитать настройки, закрыть файл), это много, особенно если вызовы malloc происходят часто. Известно, что символьной ссылке в качестве значения можно прописать все что угодно, это необязательно должен быть реально существующий файл. Так вот, можно прописать в неё нужную нам конфигурационную строчку, и тогда для чтения её потребуется не три файловых операции, а одна: readlink().

[править] Access Control List (ACL)

В UNIX используется субъект-субъектная модель разграничения доступа со множественным субъектом. Все объекты в файловой системе нумеруются по одному и тому же списку --- множественных субъектов. Субъекты бывают как уникальные --- пользователи, так и множественные, т.е. группы. И все права субъектов вычисляются по простой арифметике (3x3, было на прошлой лекции). Всё это в общем довольно естественный способ задания прав доступа, тем не менее, существует несколько use case'ов (случаев использования), когда субъект-субъектная модель работает неудобно.

Например, если какому-то конкретному пользователю надо что-то конкретное запретить, например, доступ к некоторому файлу. Это можно реализовать и в модели: для этого надо создать специальную группу, занести туда всех пользователей, кроме провинившегося, и назначить этому файлу, например, такие права: rwxrwx---

Но есть теоретическое обоснование, почему эта модель неполная: когда для некоторого файла одной группе надо дать права только на запись, другой --- только на чтение, этого в ней сделать никак нельзя. Наметим, в какой парадигме она решается: нужна уникальная идентификация не только пользователя, но и объекта. Чтобы облегчить/усложнить себе жизнь, можем еще ввести множественные объекты, т.е. группы объектов. Эти уникальные и групповые идентификаторы объектов к пользователям отношения не имеют. И на основе этих 4 таблиц: пользователей, групп пользователей, объектов, групп объектов, можно изобразить права, кто что с чем может делать. Тогда эта задача вполне легко решается.

Такой объектный способ доступа стандартизован в POSIX, называется ACL (access control list), и слово list выдаёт нам его особенность. В субъект-субъектной модели вместе с каждым объектом нужно хранить фиксированное, малое количество информации касательно прав доступа --- 9 битов плюс ещё идентификаторы пользователя и группы, суммарно в районе 70 бит), а в этой модели, информации может быть столько, что на сами объекты на диске места останется с гулькин нос.

Чтобы это обойти, в ACL вводятся разного рода механизмы: групповые политики, правила наследования, и т.п. .... Но это сильно загромождает понимание того, кто что в итоге может, особенно введение наследования. Не смотря на то,что оно поддерживается большинством Linux-систем, пользоваться ей надо в исключительных случаях. Был случай, когда школьники пришли на олимпиаду по программированию, а им всем оказался разрешен доступ на сетевой диск на запись, именно из-за какой-то ошибки в ACL.

Соответствующие команды (если нужный пакет установлен) называются getfacl/setfacl.

[править] Краткий обзор шелла как ЯП

Нынче немодно говорить, что шелл --- полный ЯП, а BAT --- неполный. Говорят, что CMD полный.

Поговорим про то, что такое скрипт --- сценарий с т. з. юних систем. Уже говорилось, что в юних, а в след за ним и в линух свойство файла быть запускаемым опр. специальным режимом доступа (использование). При этом этот файл внутри себя может быть как бинарником, а может быть и текстовым. Для вып. этого файла запускается интерпретатор, который его интерп. По умолчанию этот интерпретатор --- шелл. Именно поэтому, когда говорят скрипт, имеют в виду шеллскрипт. Это искл, которому доверять не надо. В линух принято след. правило: сценарий --- файл, который начинается с #!<интерпретатор>/ "то первая строка файла, например #!/bin/sh. Эта строчка позволяет системе решить,что этот файл должен исполняться соотв. интерпретатором. Запустили prog 1 2 3, а у prog написано #!/bin/sh, то запустится на самом деле /bin/sh prog 1 2 3, причём шелл делает так, что список аргументов начинается с prog. На самом деле, скрипты пишутся на чём угодно: perl, python, ..., лишь бы интерпретатор проигнорировал sha-bang (эту самую первую строчку). Отсюда замечательное свойство --- во многих языках строка с решётки --- комментарий. Ещё одно свойство --- сказав chmod +x, сделал из скрипта программу.

Практически на тех же правах, что и перем. окруж, определяется куча пареметров разных, в том числе для работы ... . Переменная $0 будет соотв. нулевому аргументу, $1 --- первому, и так далее до 9. Ещё есть такая команда shift, которая без параметров производит сдвижку на 1 параметр вправо (2 в 1, 3 в 2, ..., 10 в 9). Зачем это нужно: у вас там флаги, потом имена файлов. Вы флаги прошифтили, а дальше только имена файлов, можно обрабатывать их в цикле. $* --- строка целиком. $@ тоже содержит строку целиком, заведена она для того, чтобы операцию подстановки внутри кавычек. Разница при квотировании: "$*" --- одна большая строка ("$1 $2 $3"), а результатом "$@" будут отдельные параметры ("$1" "$2" "$3"). Если посмотреть на $@ то кажется, что это специфическая, контексно-зависимая штука, потому что работает иначе, но пользоваться этим удобно. Что ещё есть: $# --- количество параметров командной строки.

  • $_ --- последняя введённая польз. строка
  • $$ --- pid запущенного процесса.
  • $! --- pid последнего из процессов, запущенных в фоне

[править] Списки

Списки --- списки команд. Если захотелось, чтобы несколько команд работало вместе, например, чтобы они выводили в один файл. Можно сделать

cmd1 > f
cmd2 >> f
...

а можно сделать

{cmd1; cmd2;} > f

Про скобки: можно рассматривать их как операторные скобки. Одно из свойств фигурных скобок состоит в том, что ввод-вывод объединяется. Если для того, чтобы запустить эти команды, не надо запусктаь отдельного шелла, то они выполн. в текущем. Но если нужно, то запускаются отдельно: echo ... | read A, то ... .Если же записать круглые скобки: (cmd1; cmd2) > f, то обязательно запускается отдельный шелл. Этод удобно для того, чтобы понаопределять переменных, а потом всё забыть

[править] Условный оператор

if <список>; then <список>; [else <список>;] fi

Точки в запятыми обязательными, чтобы шелл не посчитал then очередным параметров. Встаёт вопрос, когда выполняется then, в других else. Все мы знаем,что 0 --- ложь, всё остальное --- истина. В типизированных языках есть специальный тип. Шелл заточен под работу с программами, поэтому он использует exit status. Программа по завершении возвращает exit status. Существует ячейка, которую программа по окончанию работы она заполняет всегда. Код завершения последней запущенной программы лежит в $?. На exit status распрост. след правило: если он равен 0, то программа заверш. успешно, иначе рпограмма завершилась ошибкой с кодом exit status. Условная команда в шелл выаолн. список команд, и елси он выполняется успешно, то выполняется then, иначе else. Как опр. код заверш. в списке --- по последней команде. Если код завершения --- 0, то выполняется then, иначе else.

Два амперсенда --- более короткий способ записи условного оператора. Последовательность команд может быть объединена не точками с запятыми, а && или ||. Те, кто программировал в си, знает, что там ленивое вычисление лог. выр. В шелле в a || b b выполняется тогда, кгда a завершилдась неуспешно, в && наоборот.

Пример:

test -r logfile && cat logfile || echo File not found

[править] Цикл

while <список>; do <список>; done

Есть break, continue. У каждой есть необязательный параметр, из скольки циклов выскочить. Более сложно устроен for.

for <переменная> in <строка>; do <список>; done

Пример:

for n in `ls`; do echo $n; done

Тут встречаемся с тем, что разделителем в том числе является и перевод строки

[править] case

case <список> in
  <шаблон>) список ;;
  ...
esac

При всём некрасивом синтаксисе, на самом деле, жутко удобная штука, потому что используются wildcards, т.е. производится сопоставление шаблонов.

[править] Функции

<имя>()
{
  ... $1 --- первый позиционный параметр функции
}

[править] trap

В шелле есть команда trap, которая позволяет перехватывать сигналы, посылаемые процессы. Синтаксис:

trap <функция> сигнал

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

 onexit() { trap - EXIT; cleanfile}

Первым делом в ней нужно отключить обработку EXIT, иначе shell будет бесконечно этот обработчик вызывать.

ДЗ: привести пример, что можно, или доказать, что нельзя с использованием сигналов сделать очередь для диспетчеризации процессов на разные процессоры...


UNИX, весна 2008


Лекции

01 02 03 04 05 06 07 08 09 10 11 12 13 14


Календарь

Февраль
13 20 27
Март
05 12 19 26
Апрель
02 09 16 23 30
Май
07 14
Семинары

01 02 03 04 05 06 07


Календарь

Март
21
Апрель
04
Май
16 30
Июль
11 18
Август
15


Эта статья является конспектом лекции.

Эта статья ещё не вычитана. Пожалуйста, вычитайте её и исправьте ошибки, если они есть.
Личные инструменты
Разделы