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

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

(Различия между версиями)
Перейти к: навигация, поиск
Строка 1: Строка 1:
 +
'''Диктофонная запись:''' http://esyr.org/lections/audio/uneex_2008_summer/uneex_08_03_26.ogg
 +
Зачем нужны хардлинки?
Зачем нужны хардлинки?
1. Если есть программа, которая меняет своё поведение в зависимости от имени. Для чего это нужно --- экономить байты
1. Если есть программа, которая меняет своё поведение в зависимости от имени. Для чего это нужно --- экономить байты

Версия 11:14, 31 марта 2008

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

Зачем нужны хардлинки? 1. Если есть программа, которая меняет своё поведение в зависимости от имени. Для чего это нужно --- экономить байты 2. Когда имена лежат в разных каталогах, при чём, если такой способ использования, что пользователеь файлом попользовался и удалил /* 3. Если нужно условно говоря написать конфиг, но специфичность его такова, что это специфичной функции типа маллок, и там может быть например, что забивать --- это симлинк */

Содержание

Два маленьких дополнения: софтлинки и ACL

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

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

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

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

ACL

В юнихе исп. субъект-субъектная модель со множеством субъектов. Все объекты в ФС нумеруются по одному и тому же списку --- мн. субъектов. Субъекты бывают как уникальные --- пользователи, так и группы. И все субъекты вычисл. по простой арифметике. Всё это в общем довольно естественный задания прав доступа, тем не менее, существует неск. юзкейзов, когда субъект-субъектная модель работает неудобно. Например, если какому-то пользозвателю надо что-то запретить, то для этого надо созд. спец. группу, перетаскивать всех туда... Есть теоретическое обосн., почему эта модель неполная: когда одной надо дать только на запись, другой --- только на чтение. Чтобы только наметить, в какой парадигме она решается: есть не только уник. идент. пользователя, но и объекта. Чтобы облегчить/усложнить чебе жизнь, вводим группы объектов, и вот эти уник. и групповые идент. объектов к польз. отн. не имеют, там своя классиф. И на осн. этих 4 таблиц: список польз., групп, объектов, групп объектов, можно изобразить права, кто что с чем может делать. Тогда эта задача вполне легко решается. Это стандартизовано: такой объектный способ доступа стандартизован в POSIX, называется ACL, и List выдаёт нам отличие: в субъект-субъектной инф-ции очень малый оверхед --- 9 битов плюс ещё немного суммарно в районе 60 бит), а в этой модели, что описано сейчас, может их быть много. Чтобы это обойти, водружаются групповые политики, правила наследования .... с одной стороны, это сильно загромождает понимание, кто что может, особенно введение наследования. Не смотря на то,что оно подджерживается большинством Линух-систем, пользоваться ей надо в искл. случае.

Соотв. команды называются setfacl/getfacl.

Краткий обзор шелла как ЯП

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

Поговорим про то, что такое скрипт --- сценарий с т. з. юних систем. Уже говорилось, что в юних, а в след за ним и в линух свойство файла быть запускаемым опр. специальным режимом доступа. При этом этот файл внутри себя может быть как бинарником, но файл может быть и текстовым. Для вып. этого файла запускается интерпретатор, который его интерп. По умолчанию этот файл --- шелл. Именно поэтому, когда говорят скрипт, имеют в виду шеллскрипт. Это искл, которому доверять не надо. В линух принято след. правило: сценарий --- файл, который начинается с #!<интерпретатор>/ "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, сделал из скрипта программу.

Практически на тех же правах, что и перем. окруж, определяется куча пареметров разных, в том числе для работы ... . Переменная $0 будет соотв. нулевому аргументу, $1 --- первому, и так далее до 9. Ещё етьс такая команда shift, которая без параметров производит сдвижку на 1 параметр вправо. Зачем это нужно: у вас там флаги, потом имена файлов. Вы флаги прошифтили, а дальше только имена файлов. $* --- строка целиком. $@ тоже содержит строку целиком, заведена она для того, чтобы операцию подстановки внутри кавычек. Разница при квотировании: "$*" --- одна большая строка ("$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 njulf j,hf,jnxbr --- не система, а функция. Никаких специфич. парам. там нет. Единственное, среди списка сигналов есть специальное слово EXIT, которое словом не является, а является флагом выхода из скрипта, функция ыполняется после завершения скрипта. Для чего это нужно --- для того, чтобы удалять файлы, созданные mktemp, например. Делается это следующим образом: пишется функция, которая создаёт временный файл и добавляет его в переменную, написать onexit() { trap - EXIt; cleanfile}

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

Личные инструменты
Разделы