Материалы к спецкурсу "Unix"

Структура файловой системы

В стандартной файловой системе (ФС) ОС Unix могут храниться объекты нескольких типов:

  • обычные файлы
  • каталоги
  • символические ссылки
  • специальные файлы - точки доступа к драйверам устройств
  • коммуникационные объекты FIFO
  • сокеты UNIX

Все эти объекты используют единую систему имен и имеют идентичные атрибуты, характеризующие права доступа.

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

Для хранения атрибутов файлов в ФС используется массив индексированных узлов inode (Indexed Node). Индекс - это целое число, указывающее порядковый номер inode в массиве. Для каждого файла в пределах одного раздела на диске индекс inode уникален. При этом, на разных дисках или на разных разделах одного диска ведётся своя независимая нумерация inode - так, например, индекс 2 может использоваться для корневого каталога каждого из разделов диска. Для объединения нескольких дисков в единую ФС используется виртуальная файловая система, которая пересчитывает номера inode так, чтобы обеспечивалась их уникальность. Если в Unix используется сторонняя ФС (например FAT или NTFS) то структура inode эмулируется на уровне виртуальной файловой системы.

Связь между именем и атрибутами осуществляется через объекты-каталоги. Каталоги в Unix - это таблицы, хранящие имя файла и индекс inode в массиве атрибутов. Один файл может иметь несколько имен, т.е. в различных каталогах или даже в одном каталоге могут быть записи, связывающие различные имена с одним inode.

Права доступа (R)ead, (W)rite, e(X)ecute определены по отдельности для трех категорий пользователей (U)ser,(G)roup, (O)ther. Дополнительно к правам доступа есть флаг смены владельца на время выполнения файла, смены группы на время выполнения файла и признак «липкости» (sticky bit), что бы он не означал.

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

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

Стандартные каталоги UNIX

Во всех Unix-подобных ОС (FreeBSD, Linux, с некоторыми изменениями в Android и MacOS X) используется традиционная схема именования каталогов, которая описывается стандартом Filesystem Hierarchy Standard. В целом структура каталогов представляет из себя дерево с единым корнем, обозначаемым /.

В корневом каталоге находятся следующие подкаталоги:

"Базовые" каталоги, которые для правильного старта системы должны быть доступны в момент загрузки ядра:
/etc – конфигурационные файлы;
/bin – минимальный набор утилит пользователя, необходимых для запуска системы;
/sbin – минимальный набор утилит администратора, необходимых для запуска системы;
/lib – динамические библиотеки для утилит из /bin и /sbin. В Linux в каталоге /lib/modules размещаются модули ядра;
/dev – каталог, содержащий набор специальных файлов устройств – точек доступа к драйверам;
/tmp – каталог для временных файлов;

Дополнительные каталоги:
/root – «домашний» каталог администратора (пользователя root). /usr – основной каталог, содержащий программы, библиотеки, файлы документации и пр.;
/var – каталог для данных большого и часто меняющегося размера – лог-файлов, баз данных, временных файлов печати и почты и пр.;
/opt – каталог для установки коммерческих программ;
/home – каталог для размещения «домашних» каталогов пользователей.

Виртуальные файловые системы в каталогах /proc и /sys предоставляют доступ к переменным ядра ОС, оформленным в виде виртуальных файлов.

Имя каталога /usr произошло от слова User (пользователь) в те времена, когда диски были маленькими и полный комплект программ на них не входил. Каждому пользователю приходилось создавать свой рабочий набор программ на отдельном диске, который и подключался в каталог /usr. В большинстве современных Unix-подобных ОС все стандартные программы размещаются именно в каталоге /usr (Android, скорее, исключение).

В каталоге /usr находятся следующие подкаталоги:
/usr/bin, /usr/sbin, /usr/lib – по аналогии с каталогами в корне;
/usr/include – заголовочные файлы для компиляторов языков C и C++ ;
/usr/share – документация, шрифты, программы на скриптовых языках и другие неизменяемые данные, которые могут быть использованы через сетевую файловую систему с любой версией программ и для любой архитектуры процессора;

/usr/local – каталог для установки программ, не включенных в основную поставку системы. Название получил в то время, когда разработчики Unix'а активно экспериментировали с сетевыми файловыми системами. Считалось, что каталог /usr может быть подключен по сети для всех компьютеров в локальной сети, а /usr/local – расположен на локальном диске. В /usr/local находятся стандартные подкаталоги etc, bin, sbin, lib.

Каталог /var предназначен для хранения больших объемов данных. Иногда его располагают на отдельном большом разделе диска. В /var можно отметить следующие подкаталоги:
/var/log – лог-файлы;
/var/mail – почтовые ящики пользователей;
/var/tmp – общедоступный каталог для временных файлов. В некоторых системах /tmp размещается на маленьком разделе диска, в этом случае /var/tmp - это каталог в котором можно размещать большие временные файлы.

В зависимости от используемой ОС, стадии загрузки системы и прав доступа программе могут быть доступны только некоторые из перечисленных каталогов. Существуют только два элемента файловой системы, которые доступны всегда - каталог /tmp и файл управляющего терминала /dev/tty.

Основные системные команды Unix

Управление файлами и каталогами

ls – список файлов (LiSt). По умолчанию выводится текущий каталог.
Полезные опции: -a – включать файлы с именами, начинающимися с точки; -R – рекурсивно показывать содержимое подкаталогов; -l – вывод подробной информация о файлах:

ls -l dir – подробная информация о файлах в каталоге dir
ls -ld dir – подробная информация о самом каталоге dir

touch file – если файл не существует, то он создается; иначе время модификации файла устанавливается в текущее.

rm file – удалить файл (ReMove).
Полезные опции: -R или -r – рекурсивное удаление каталогов, -i – интерактивные запросы на подтверждение удаления, -f – отмена интерактивного режима.

cp file1 file2 – копирование файла (CoPy) file1 в file2
cp file1 file2 file3 dir – копирование группы файлов в каталог dir
cp -R dir1 dir2 – копирование каталога dir1 со всеми его файлами и подкаталогами в каталог dir2

mv file1 file2 – переименование файла (MoVe);
mv file dir – перемещение файла в каталог dir. Если каталог находится в том же разделе диска, что и файл, то происходит создание новой записи в каталоге без копирования данных. Если файл и каталог находятся в разных разделах, то происходит копирование содержимого файла на новый раздел, после чего старая копия удаляется.

mkdir dir – создать каталог (MaKe DIRectory) с именем dir
rmdir dir – удалить каталог (ReMove DIRectory) dir. Удаление возможно только в том случае, когда каталог пуст.
rm -R dir – рекурсивно удалить каталог со всеми вложенными подкаталогами и файлами.

ln file1 file2 – создать имя (LiNk) file2 для file1
ln -s file1 file2 – создать символическую ссылку с именем file2, указывающую на file1
ln -s /etc/passwd – создать в текущем каталоге символическую ссылку с именем passwd , указывающую на /etc/passwd
ln -s /etc/passwd dir – создать в подкаталоге dir символическую ссылку с именем passwd, указывающую на /etc/passwd
ln -s file dir – ошибка. Подразумевается, что в подкаталоге dir будет создана ссылка с именем file, указывающая на file из текущего каталога. Но в символическую ссылку записывается не объект ФС, а текст, заданный в первом параметре. В результате команды в подкаталоге dir появится ссылка с именем file, ссылающаяся на file, т.е. сама на себя.
ln -s ../file dir – возможный вариант правильного написания предыдущей команды.

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

Все команды этой группы с опцией -R могут применяться к каталогу. В этом случае команда применяется к каталогу, а также рекурсивно применяется ко всем файлам и подкаталогам, расположенным внутри этого каталога.

chown user file – смена владельца файла file на user. Команда может выполняться только администратором root.
chgrp group file – смена группы владельцев файла. Для успешного выполнения команды пользователь должен быть членом группы group или администратором root.
chown user:group file – одновременная смена владельца и группы.

chmod u+w file – смена прав доступа к файлу или каталогу. В данном случае добавление владельцу файла права на запись в этот файл. Право доступа может поменять владелец файла или администратор root.

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

  • Для кого меняются права: u – пользователь (User), g – группа (Group), o – остальные (Other)
  • Операция с правами: + – добавить право, - – удалить право, = – сбросить все существующие права и добавить перечисленные
  • Какие права меняются: r – чтение (Read), w – запись (Write), x – исполнение (eXecute)

Управление процессами

В отличие от команд управления файлами, команды управления процессами могут сильно отличаться в разных ОС. Поэтому приведены версии команд, которые будут работать в ОС Linux.

ps – выдача списка процессов (Process liSt). По умолчанию выдаются процессы, запущенные в текущем сеансе
ps -e – выдача списка всех запущенных процессов (в коммерческих версиях Unix'а и в Linux)
ps ax – выдача списка всех запущенных процессов (FreeBSD и Linux)
ps ax --forest – группировка процессов по признаку родительский процесс/дочерний процесс (только Linux)

kill -KILL 23456 – принудительное завершение процесса с идентификатором (pid) 23456

Программы сжатия и архивирования

Программы сжатия данных gzip, bzip2, xz

Программы gzip, bzip2, xz предназначены для сжатия одиночных файлов. Сжатые файлы имеют расширения .gz, bz2, xz соответственно. Кроме того, распознаются расширения .tgz, .tbz, .txz, являющиеся сокращением от двойных расширений .tar.gz, .tar.bz2, .tar.xz.

Для распаковки используются эти же программы с опцией -d (decompress).

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

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

У программ сжатия есть альтернативные имена. Запуск по этим именам эквивалентен запуску с некоторым набором опций.
gunzip, bunzip2, unxz = запуск с опцией -d
zcat, bzcat, xzcat = запуск с опцией -c

Вспомогательные программы:
zmore file.gz = zcat file.gz | more
zgrep file.gz text = zcat file.gz | grep text
zdiff file1.gz file2.gz = zcat file1.gz > /tmp/xxfile1; zcat file2.gz > /tmp/xxfile2; diff /tmp/xxfile1 /tmp/xxfile2; rm /tmp/xxfile1 /tmp/xxfile2

Примеры

Сжатие файла
gzip file

Распаковка файла
gzip -d file.gz

Сжатие "на лету"
echo Test | gzip > test.gz

Распаковка в стандартный вывод и подсчет строк в распакованном потоке
gzip -d -c test.gz | wc -l

Архиватор tar

Архиватор tar (Tape ARchiver) изначально предназначен для создания архивов файлов на магнитных лентах. При архивировании после списка опций указываются имена файлов и каталогов, которые надо поместить в архив. Для того, чтобы указать файл архива, используется опция -f имя_файла (обычного или файла-устройства). Если вместо имени файла указан "-", то для ввода/вывода архива используется стандартный ввод/вывод.

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

Основные операции с архивом задаются соответствующими опциями :
– Создать архив (Create)
-t – Проверить архив и выдать список заархивированых файлов (Test)
-x – Извлечь файлы из архива (eXtract)

Дополнительные опции, используемые совместно с опциями операций:
-v – Печатать информацию о процессе архивирования/извлечения файлов
-z – Использовать gzip для дополнительного сжатия/распаковки архива
-j – Использовать bzip2 для дополнительного сжатия/распаковки архива
-J – Использовать xz для дополнительного сжатия/распаковки архива (только последние версии)

Новые версии gnutar умеют при извлечении файлов из архива определять программу сжатия автоматически. Для старых версий требуется явно указывать опцию. Версии tar из коммерческих вариантов Unix вообще не поддерживают опции сжатия и требуют построения конвейера из программы сжатия и архиватора tar.

Опции можно писать без знака минус и писать несколько опций вместе, начиная с опции операции и заканчивая опцией задания файла архива.

Примеры

Заархивировать каталог /etc в архив etc.tar
tar cf etc.tar /etc

Заархивировать каталог /etc в архив etc.tbz, на лету сжимая архив программой bzip2 и выдавая в процессе архивирования имена обрабатываемых файлов
tar cjvf etc.tbz /etc

Выдать содержимое архива etc.tbz
tar tf etc.tbz - современная версия tar
tar tjf etc.tbz - более ранние версии tar

Распаковать архив etc.tgz в современной версии tar
tar xf etc.tgz

Распаковать архив, сжатый программой xz, версией tar без встроенной поддержки этого формата
xzcat etc.txz | tar xf -

Переслать каталог с вложенными файлами и подкаталогами в домашний каталог пользователя user на компьютер remotehos.example, используя программу ssh
tar cf - mydir/ | ssh user@remotehos.example tar xf -

Архиватор cpio

Программа cpio (CoPy In/Out) предназначена для чтения файлов из архива (In) и записи файлов в архив (Out), а также для копирования файлов из каталога в каталог (Pass through). По умолчанию чтение/запись архива производится через стандартный ввод/вывод. Чтобы явно указать файл архива, используется опция -F. В программу встроены средства удаленного протокола через rsh или ssh. Для работы с архивом на удалённой машине он задаётся в формате -F user@host:file. Для администраторов Linux'a программа интересна тем, что с её помощью создаются установочные пакеты формата RPM и образы начальной загрузки initrd.

Основные опции:

cpio -i -d < <archive> – чтение архива со стандартного ввода. Дополнительная опция -d указывает, что надо создавать структуру подкаталогов, сохраненную в архиве.
find . -depth -print0 | cpio -o --null > <archive> – чтение имен файлов со стандартного ввода и вывод архива на стандартный вывод. Опция -print0 команды find и --null команды cpio указывают на то, что в качестве разделителя имён файлов используется нулевой символ '\0'. Это позволяет корректно отработать имена, содержащие пробелы, табуляции и переводы строк.
find . -name z\* -depth -print0 | cpio -p --null -d /tmp – скопировать все файлы с именами на букву z из текущего каталога с подкаталогами в каталог /tmp. Опция -d указывает, что в целевом каталоге надо создавать необходимые подкаталоги.

Просмотр текста командами more и less

Для удобного просмотра текста из файла или со стандартного вывода программы используются программы постраничного пролистывания – "пэйджеры".

more

Простейшая программа для постраничного просмотра текста more используется с именем файла(ов) в качестве параметра или как последняя команда в цепочке перенаправлений ввода/вывода. С помощью опций +<число> или +/<образец текста> можно начать просмотр с интересующей строки.

# Просмотр файла file1 с 20-ой строки
more +20 file1

# Поиск в выводе программы grep подстроки 13:00 и просмотр вывода, начиная с этого места
grep ntpd /var/log/messages | more +/13:00

more умеет листать текст вперёд. Текст из файла, в принципе, можно пролистать назад, но это нетипичное использование more.

Основные интерактивные команды more похожи на команды редактора vi:

  • h – help
  • q – выход
  • SPACE – пролистать один экран
  • d – пролистать пол экрана
  • RETURN – пролистать одну строку
  • /pattern – пролистать до строки содержащей подстроку pattern
  • n – повторить поиск подстроки
  • = – показать номер текущей строки
  • :n – перейти к следующему файлу
  • :p – вернуться к предыдущему файлу
  • :f – напечатать имя текущего файла и номер строки в нем
  • ! – запуск shell-команды

Только при просмотре файлов:

  • b – пролистать экран назад
  • v – вызвать текстовый редактор, установив курсор на текущую строку

less

less – существенно более развитая команда для пролистывания текста. При чтении данных со стандартного ввода она создает буфер, который позволяет листать текст как вперед, так и назад, а также искать как по направлению к концу, так и по направлению к началу текста. Заполнение буфера идет блоками по 64KB, поэтому (если текст на стандартный ввод подается медленно) возможна ситуация "подвисания", когда less показывает очередные поступившие строки, но не позволяет выполнить какую-либо команду.

less понимает все команды more плюс свои.

  • h – вызов справки
  • q – выход
  • SPACE – на экран вперёд
  • b – пролистать экран назад
  • k и j или стрелки вверх и вниз – вертикальная прокрутка по строке
  • g – перейти на 1-ую строку
  • <N>g – перейти на строку N
  • G – перейти на последнюю строку
  • F – перейти на последнюю строку файла и ожидать записи новых строк (аналог tail -f, не работает со стандартным вводом)
  • /pattern – поиск по шаблону вперёд
  • ?pattern – поиск по шаблону назад
  • n – следующее совпадение
  • N – предыдущее совпадение
  • mбуква – отметить позицию буквой
  • 'буква (апостоф и буква) – перейти на отмеченную позицию
  • ! – запуск shell-команды (% – имя текущего файла, к примеру: ! cat % > /tmp/foobar.txt)

Только для файла

  • v – запуск редактора

Только для стандартного ввода

  • s filename – сохранить выводимый текст в файл filename

Параметры вывода текста less можно указывать как в виде опций, так и в интерактивном режиме. Повторный ввод опции в интерактивном режиме отменяет действие.

  • -g – при поиске подсвечивать только текущее найденное слово (по умолчанию подсвечиваются все вхождения)
  • -N – показывать номера строк

Установка программы из исходных текстов

Очень многие программы для Unix, распространяемые в исходных текстах, используют для автоматической настройки под операционную систему средства autoconf и automake. Подобные программы компилируются и устанавливаются типовым образом.

Общепринятая схема сборки программы выглядит так:

  • Скачать архив с программой и необходимые патчи от сторонних разработчиков. Например, с помощью консольной программы скачивания wget
    wget ftp://ftp.chg.ru/prog.tgz
    wget http://home.yandex.ru/prog-my.patch

  • Проверить, что архив распакуется в отдельный каталог. Если архив распаковывается в текущий каталог, то создать рабочий каталог, скопировать архив туда. 1
    tar tzf prog.tgz

  • Распаковать архив
    tar xzf prog.tgz

  • Перейти в каталог с распакованными исходниками
    cd prog

  • Прочитать файлы README и INSTALL :)

  • Применить патч 2
    patch -p1 < ../prog-my.patch

  • Настроить процесс сборки под конкретную ОС
    ./configure

  • Скомпилировать программу
    make

  • Установить в стандартный каталог (требуются права root'а)
    make install


  1. Прочитать про архиватор tar ↩︎

  2. patch -p1 – Как правило, в файлах патча имена представлены в виде пар oldversion/file.c newversion/file.c. Опция -p1 означает, что из имен файлов надо отбросить один уровень каталогов. ↩︎

Утилиты работы с текстом

Unix обладает богатым набором утилит для работы с текстом. Некоторые из них позволяют создать на основе текстовых файлов маленькое подобие базы данных. Все утилиты, рассматриваемые в этом разделе, могут работать как с файлами (наборами файлов), так и со стандартным вводом. Часть утилит может работать с двоичными файлами.

Будем рассматривать текстовые файлы как набор записей-строк, возможно, состоящих из полей, разделённых знаками препинания, слов, разделённых пробелами, и букв.

wc – подсчёт строк, слов и букв. По умолчанию выдаёт все три значения. Интересующую величину можно выбрать с помощью опции -l, -w, -c соответственно.

wc -w /etc/passwd # подсчёт слов в файле passwd
ls | wc -l  # подсчёт числа файлов в текущем каталоге

split – разбиение файла на меньшие, определённого размера. Может разбивать текстовые файлы по строкам и любые – по байтам. По умолчанию читает со стандартного ввода и создает файлы с именами вида xaa, xab и т.д. По умолчанию разбиение идёт по 1000 строк в файле.

cat – объединение файлов. Работает не только с текстовыми файлами, но и с двоичными. Возможно объединение содержимого файлов со стандартным вводом. В этом случае в качестве одного или нескольких имен файлов в командной строке указывается знак -. Пример:

echo "------------" | cat file1 - file2 #Вывод содержимого двух файлов, разделённого строкой из минусов

head – выборка первых строк (байтов) файла:

head -n 12 file  # первые  12 строк
head -c 12 file  # первые  12 байтов
head -n -12 file  # с начала, отбросив 12 строк с конца

tail – выборка последних строк (байтов) файла:

tail -n 12 file  # последние  12 строк
tail -c 12 file  # последние  12 байтов
tail -n +12 file # с 12-ой строки до конца

tail и head – объединение команд обеспечивает выборку диапазона строк:

# 24 строки, начиная с 12-ой (с 12 по 35)
tail -n +12 file | head -n 24
# или
head -n 35 file | tail -n 24

cut – выделение столбца. Довольно неудобная команда, ориентированная на файлы с колонками, разделёнными определённым символом (по умолчанию - символом табуляции), или на файлы с колонками в фиксированных позициях. Опции -f - номер колонки для вывода, -d - символ разделитель. Пример:

# Вывод списка домашних каталогов пользователей (шестое поле в файле passwd)
cut -f6 -d':' /etc/passwd

awk – альтернатива cut. Вообще-то, awk – это довольно развитый язык программирования, но в данном случае нас интересует способность awk разбирать строку на элементы, разделённые пробельными символами. Примеры:

awk '{print $9}' #Вырезание девятой колонки
awk '{print $5 $4 $3 $2 $1}'  #Перестановка местами первых пяти колонок

sort– сортировка строк. Полезные опции: -n - числовая сортировка, т.е. 2 идёт раньше чем 11; -kN - сортировка по колонке номер N. Колонки разделяются произвольным числом пробелов и табуляций. Пример:

ls -l | sort -n -k5 #Сортировка списка файлов по размеру (пятая колонка)

uniq – обработка повторяющихся строк. Умеет отбрасывать повторяющиеся строки и подсчитывать число повторов. Удобно применять вместе с sort. uniq может сравнивать строки целиком или начиная с некоторой позиции до конца строки.

grep – поиск строк по образцу. По умолчанию образец интерпретируется как регулярное выражение. Название программы происходит от команды редактора ed "g/re/p" - перейти к строке, содержащей регулярное выражение re и напечатать эту строку. Если нужно искать символы, имеющие особый смысл в регулярном выражении, то их нужно экранировать через слэш. Пример:

echo abc$ | grep c\\$  #Правильно
echo abc$ | grep 'c\$' #Правильно
echo abc$ | grep c$    #Строка не найдена

join – слияние файлов по ключевому полю. Файлы должны быть предварительно отсортированы. Пример слияния файлов file1 и file2, причем в первом файле ключ находится во второй колонке, а в о втором - ключ в третьей колонке:

join -1 2 -2 3 <(sort -k2 file1) <(sort -k3 file2)

Аргументы команды: опции, строки, файлы

При запуске программы в Unix указывается имя исполняемого файла и список параметров, разделённых пробелами. Дополнительно, может быть задано перенаправление стандартных файлов ввода/вывода.

В зависимости от программы, параметры могут интерпретироваться как опции, как строки или как имена файлов. Единого стандарта нет, но есть несколько популярных соглашений. Однобуквенные опции, как правило, начинаются со знака минус: -x или -x значение, опции с длинными именами - с двух минусов: --xxx-xxx или --xxx-xxx=значение. Программы, которые не работают с файлами, могут использовать опции без знака минус.

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

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

Примеры:

cat file # Команда cat интерпретирует параметр как имя файла
echo file # Команда echo интерпретирует параметр как текст
cat -n file # Обе команды интерпретируют -n как опцию
echo -n file # правда, с разным значением
cat -- -n file # Команда cat интерпретирует "--" как конец опций
echo -- -n file # Команда echo не интерпретирует "--" как конец опций
cat - file # Команда cat интерпретирует "-" как чтение из стандартного ввода
echo - file # Команда echo не читает из файлов и не придает "-" особого значения

dd if=file of=/dev/null # Команда dd использует нестандартный формат опций
ps ax --forest # Команда ps все аргументы трактует как опции. Короткие опции используются без минуса
java -version # java использует длинные опции с одним минусом

Команда test и [[expr]]

В командном языке bash операторы if и while могут использовать в качестве условия код завершения произвольной программы. Код ответа 0 интерпретируется как "истина", любой другой - как "ложь". Вместо if можно использовать операторы условного выполнения cmd1 && cmd2 - выполнить cmd2 если cmd1 завершилась успешно и cmd1 || cmd2 - выполнить cmd2 если cmd1 завершилась неуспешно.

Пример:

if grep --silent aaa file; then echo file \"file\" contain \"aaa\"; fi
grep --silent aaa file && echo file \"file\" contain \"aaa\"
grep --silent aaa file || echo file \"file\" not contain \"aaa\"

Для того, чтобы в качестве условия можно было бы писать традиционные выражения, была придумана команда test. Команда получает операторы и операнды в виде отдельных аргументов командной строки, вычисляет логическое условие и возвращает 0, 1 или 2 (в случае синтаксической ошибки).

Пример:

test "abc" = "cde" || echo "abc" not equal "cde"

Для красоты записи программа test имеет ещё одно имя - [ и вспомогательный последний аргумент ] . Две строчки ниже эквивалентны:

if test 1 -gt 0; then echo 1 \> 0;fi
if [ 1 -gt 0 ]; then echo 1 \> 0;fi

Аргументы команды test подвергаются обычным подстановкам и разбиением на слова, что часто приводит к ошибкам:

[ "A" > "B" ]       # неправильно
[ "A" \> "B" ]      # правильно
[ $A = HELLO ]      # ошибка если переменная A не определена, содержит пробелы или символы подстановки
[ "$A" = HELLO ]    # ошибка если $A начинается с минуса. Например -eq
[ x"$A" = xHELLO ]  # прием, позволяющий корректно провести сравнение

Для того, чтобы преодолеть указанные проблемы в язык введена синтаксическая конструкция [[expr]], которая разбирает выражение expr по тем же правилам, что и команда test, но при этом внутри скобок не производится подстановка имен файлов, перенаправление ввода/вывода и разбиение содержимого переменных на слова.

[[expr]] в отличие от [ expr ] не является независимой командой, что можно увидеть на примерах:

\[ -e file \]        # нормально
[ -e file ]          # то же самое
\[\[ -e file \]\]  # [[: command not found
[[ -e file ]]       # нормально

Набор операторов test и [[

Проверки объектов файловой системы: op path

  • -e объект существует
  • -f это файл
  • -s файл не нулевого размера
  • -d каталог
  • -b блочное устройство (например диск)
  • -c байтовое устройство (например модем)
  • -p именованный канал
  • -h -L символический линк
  • -S сокет

  • -r доступен на чтение

  • -w доступен на запись
  • -x доступен на выполнение

Проверка строк: op string

  • -z пустая строка
  • -n непустая строка

Сравнение строк: string1 op string2

  • = равны
  • != неравны
  • > больше
  • < меньше

Сравнение чисел: num1 op num2

  • -eq равны
  • -ne неравны
  • -gt больше
  • -lt меньше

Группировка: (expr)

Отрицание: ! expr

Логические операции в test: expr1 op expr2

  • -a И
  • -o ИЛИ

Логические операции в [[: expr1 op expr2

  • && И
  • || ИЛИ

Редактор Ed

Редактор ed - очень простой интерактивный текстовый редактор, включенный в спецификацию стандарта POSIX. Этот редактор должен присутствовать в любой Unix подобной ОС, в том числе Linux. Фактически это так и есть, но некоторые реализациях могут отклоняться от стандарта. Например, busybox в эмуляторе Unix'а MobaXterm выдает приглашение на ввод команд и лишён поддержки регулярных выражений.

Набор команд ed используется в потоковом редакторе sed, а так же в популярном редакторе vim (там они доступны после ввода управляющего символа ':' ).

Редактор ed не имеет пользовательского интерфейса и не выводит на экран текст редактируемого файла. Это позволяет работать с редактором ed на очень медленных линиях связи и при плохом отклике системы (например при чрезмерной нагрузке).

При старте редактор ed считывает редактируемый файл в буфер в оперативной памяти и выполняет все операции с этим буфером. Буфер сохраняется в файл только после явного вызова команды записи. Такой способ редактирования отличает редактор ed от потокового редактора sed и не позволяет работать в ed с большими файлами.

Запуск редактора

ed [file]

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

Команды sed

Очень краткая сводка

:  # label
=  # line_number
a  # append_text_to_stdout_after_flush
b  # branch_unconditional             
c  # range_change                     
d  # pattern_delete_top/cycle          
D  # pattern_ltrunc(line+nl)_top/cycle 
g  # pattern=hold                      
G  # pattern+=nl+hold                  
h  # hold=pattern                      
H  # hold+=nl+pattern                  
i  # insert_text_to_stdout_now         
l  # pattern_list                       
n  # pattern_flush=nextline_continue   
N  # pattern+=nl+nextline              
p  # pattern_print                     
P  # pattern_first_line_print          
q  # flush_quit                        
r  # append_file_to_stdout_after_flush 
s  # substitute                                          
t  # branch_on_substitute              
w  # append_pattern_to_file_now         
x  # swap_pattern_and_hold             
y  # transform_chars                

Команды редактора ed

Структура команд

Большинство команд ed имеют вид:

[addr]C[args]

Где addr - адреса строк, к которым надо применить команду, C - односимвольная команда, args - дополнительные аргументы команды. Адрес addr может отсутствовать, указывать на одну строку или на диапазон строк. По умолчанию, команды редактирования применяется к текущей строке, а файловые команды ко всему буферу.

Адреса

Адреса задаются следующими способами:

По номерам (n обозначает число), как результат поиска регулярного выражения, как смещение относительно известного адреса или как диапазон от адреса до адреса:

  • n - номер строки. 0 означает строку перед первой;
  • $ - последняя строка в буфере;
  • . - текущая строка. На старте устанавливается в $;
  • /RE/ - первая строка соответствующая регулярному выражению RE. Поиск идёт вниз по тексту Если RE не найдено до конца, то поиск продолжается по кругу с начала. В sed - все строки соответствующие выражению RE.
  • ?RE? - то же, что и /RE. но поиск идёт вверх по тексту . Не актуально для sed.
  • addr+n или addr-n - смещение относительно адреса, например, /RE/+2 или $-3 (четвертая строка с конца);
  • addr1,addr2 - диапазон от и до включительно;
  • [addr1,addr2]g/RE/ - все строки в диапазоне addr1-addr2, соответствующие регулярному выражению RE;
  • [addr1,addr2]v/RE/ - все строки в диапазоне addr1-addr2, не соответствующие регулярному выражению RE;
  • 'C - строка, помеченная символом C. Метка устанавливается командой [addr]kC.

Диапазон может указываться через точку с запятой. В этом случае если адрес addr2 задан в виде поиска регулярного выражения, то при использовании запятой поиск ведётся от строки, следующей за текущей строкой, а при использовании точки с запятой - от строки, следующей за адресом addr1.

Команды

Общие

  • q - завершить работу
  • Q - забыть изменения и завершить работу
  • u - отменить изменения, сделанные последней командой редактирования
  • ffile - задать текущее имя файла. Удобно если ed запускался без указания имени файла.
  • [addr]rfile - вставить содержимое файла после адреса. По умолчанию в конец буфера. r!cmd - выполнить шелловскую команду и вставить её вывод
  • efile - удалить содержимое буфера и начать редактировать новый файл. e!cmd - аналогично r!cmd
  • [addr1,addr2]w[file] - записать буфер в файл (можно указать новое имя)

Ввод строк

  • [addr]a - вставить строки после указанной
  • [addr]i - вставить строки перед указанной
  • [addr1,addr2]с - удалить строки из диапазона и вставить вместо них новые

В командах вставки признаком конца ввода является строка состоящая из одного символа точки и перевода строки. Для ввода одной точки в строке вводятся две точки.

Печать строк

  • [addr1,addr2]p - напечатать строки из диапазона
  • [addr1,addr2]n - напечатать строки из диапазона, вставив перед каждой её номер и символ табуляции.

Удаление и копирование

  • [addr1,addr2]d - удалить строки
  • [addr1,addr2]m[addr] - переместить строки в позицию после адреса addr. Если addr==0, то в начало буфера.
  • [addr1,addr2]m[addr] - скопировать строки в позицию после адреса addr.

Контекстная замена

  • s/SRC/DST/opt произвести контекстную замену в строке. Opt: g - все вхождения в строке, i - игнорировать регистр.

Регулярные выражения

  • Для группировки используются скобки \( и \)
  • Найденные группы обозначаются \1, \2...
  • ^, ., $ - начало строки, произвольный символ, конец строки
      • повторитель предыдущего символа или группы от 0 до бесконечности
  • {m,n} - повторитель от m до n. {m} означает ровно m вхождений; {m,} - по крайней мере m вхождений; {m,n} - любое число вхождений от m до n включительно

Редактор Vim

Редактор vim (Vi IMprooved) является развитием vi (VIsual editor). В настоящее время в большинстве дистрибутивов под именем vi поставляется именно vim. В CentOS поставляются три пакета vim-minimal – vi, vim-enhanced – собственно vim и vim-common, набор макросов и вспомогательных программ. Благодаря набору макросов осуществляется подсветка синтаксиса для многих языков программирования, запуск программ на компиляцию, просмотр определения переменных и макросов и т.п.

Редактор имеет 5 режимов (modes):
«Нормальный»: текст не вводится, клавиши h,j,k,l (или стрелки) перемещают курсор, все остальные клавиши и их последовательности выполняют различные команды;
«Вставки/замены»: обычное экранное редактирование. Стрелки могут или не работать в зависимости от программы удаленного доступа;
«Визуальный» или «Выделения»: режим выделения текста с помощью клавиш перемещения курсора или специальных меток;
«Повтора»: после ввода числа в нормальном режиме следующая команда выполнится соответствующее количество раз. Например 5dd пять раз выполнит команду удаления строки;
«Командный»: для ввода команд, для которых не назначены управляющие клавиши.

Клавиша <Esc> (иногда – два нажатия) возвращает из любого режима в «нормальный».
i, a, R, o, O – переводит из «нормального» режима в режим «вставки».
Двоеточие из «нормального» режима переводит в «командный» режим.
Число переводит из «нормального» режима переводят в режим «повтора».
Символы v, V и Ctrl v – переводят из «нормального» режима в «визуальный».

Команды vim для программиста

Включить выключить автовыравнивание строк:
:set autoindent (:set ai)
:set noautoindent (:set noai)

Включить выключить подсветку синтаксиса:
:syntax on
:syntax off

Установить язык программирования если vim не распознал его автоматически:
set syntax=sh

Запустить make в текущем каталоге:
:make [param]

Перед запуском make желательно установить автоматическое сохранения редактируемых файлов перед компиляцией:
:set autowrite on

После завершения компиляции:
:cl - список ошибок
:cc [num] - показать ошибку с номером num или текущую
:cn - следующая ошибка
:cp - предыдущая ошибка

В режиме редактирования:
[i – просмотреть определение (первое вхождение в тексте) переменной
[d – просмотреть определение макроса (в языке Си)
% – найти парную скобку

Ctl-n или Ctrl-p – автодополнение, подстановка слов из имеющейся программы (а в Си и из заголовочных файлов) по введенным первым буквам
Ctrl-X Ctrl-L- автодополнение строки

Простые команды Vi

А любом режиме Esc, чтобы вернуться в нормальный. На некоторых клавиатурах Esc срабатывает с задержкой, поэтому kexit вводить Esc Esc/

В нормальном режиме:
:help [command] - просмотреть подсказку по vim в целом или посвященную команде command.
:q - выйти если в файле не было изменений
:wq, :x - записать и выйти
:q! - выйти без сохранения

u – UNDO последнее действие
U – UNDO вся строка
Ctrl-R – REDO

Переход в режим выделения
v - режим выделения символов и строк
V - режим выделения строк
Ctrl v - режим выделения прямоугольного блока символов

В визуальном режиме можно выделить блок, а затем
d – удалить в буфер (del)
с – удалить в буфер и перейти в режим вставки (cut)
y – копировать в буфер без удаления (yank)

Удаление в буфер
x - один символ
dw - слово
dd - строка

Вставка из буфера

p – вставить (paste) перед курсором
P - p – вставить после курсора

Переход в режим редактирования
i - перейти в режим вставки с позиции курсора
a - перейти в режим вставки с позиции после курсора
o - добавить пустую строку ниже и перейти в режим вставки
O - добавить пустую строку выше и перейти в режим вставки
R - перейти в режим замены
rx - заменить текущий символ на x

Позиционироваться в файле
:nnn - перейти на строку с номером nnn. :0 – начало файла, :$ или G – конец файла
) или ( – следующее или предыдущее предложение
} или { – то же для параграфа
]] или [[ – то же для секции, функции
% – ответная скобка (matching)
`` – предыдущее местонахождение, с точностью до символа
'' (два апострофа) – то же, с точностью до строки

Метки, к которым всегда можно вернуться:
mx – пометить текущую позицию буквой “x” (буква, разумеется, любая)
`x – перейти к метке “x”
'x – перейти к строке с меткой “x”

Поиск/замена:
/text – искать “text” ниже текущей позиции
?text – то же, но выше
n – повторить поиск в том же направлении
N – то же, но в обратном направлении
* – найти и пометить слово такое же, как под курсором ниже по файлу
# – то же, но выше по файлу

:[address]s/text/replacement/[gci] – в строках заданных address заменить “text” на “replacement”. Опции: g (Global)-все, c (Confirm) – с запросом, i (case Insensitive) -игнорируя регистр

Синтаксис bash

Краткий свод управляющих конструкций языка программирования bash.

Во всех управляющих конструкциях в качестве логического значения используется код возврата из программы, указанной в качестве условия. Код возврата 0 – истина, любое другое значение – ложь. Программа true – всегда завершается с кодом 0, false – всегда завершается с кодом 1. Команда test (она же [...] ) вычисляет код ответа на основе выражения, переданного через параметры командной строки.

Конструкции могут быть записаны в несколько строк, или в одну с использованием разделителя ";".

Последовательности команд. Возвращают код ответа последней выполненной команды.
; - оператор безусловного последовательного выполнения команд
&& оператор И. Правая часть не выполняется если левая выполнилась неуспешно.
|| оператор ИЛИ. Правая часть не выполняется если левая выполнилась успешно.

Оператор if – условное выполнение.
if cmd
then
command...
else
command...
fi

Запись в одну строку
if cmd ; then command1;command2…;else command3;command4…;fi

Цикл while выполняется, пока команда условие возвращает 0
while cmd
do
command...
done
Запись в одну строку
while cmd; do command1; command2;done

Пример с использованием встроенной функцией test
VAR0=0; LIMIT=10
while [ "${VAR0}" -lt "${LIMIT}" ];do
echo -n "${VAR0} " # -n подавляет перевод строки
VAR0=`expr ${VAR0} + 1`
done

Пример в сочетании c арифметической подстановкой
a=1
while (( a <= LIMIT )) ; do # В (()) $ не нужен
echo -n "$a "
((a += 1)) # В арифметической подстановке есть оператор +=
done

Пример с командой read, которая read читает строки из стандартного ввода. read разбивает строку на слова и сохраняет их в указанных переменных. Если переменные не заданы, то read сохраняет всю строку в переменной REPLY. Если необходимо читать посимвольно, то команде read можно указать опцию -n 1
while read; do
echo $REPLY
done < file.txt

Цикл until аналогичен while, но имеет обратное условие
until [condition-is-true]; do
command...
done

Цикл for выполняется путем последовательной подстановки в переменную цикла значений из списка
for ARG in LIST; do
command...
done

Простая форма
for ARG in "$VAR1" "$VAR2" "$VAR3" ; do
echo $ARG
done

В сочетании с подстановкой имен файлов по шаблону
for FILE in [ab]*; do
echo "$FILE" # В отличие от echo [ab]*, имена печатаются в отдельных строках
done

В сочетании с арифметической подстановкой
LIMIT=5
for ((a=1; a <= LIMIT ; a++)); do # $ не нужен ни перед скобками ни перед именами переменных
echo -n "$a "
done

В сочетании с программой seq
LIMIT=5
for ARG in `seq 1 $LIMIT`;do
echo -n "$ARG "
done

Оператор case выбор одного из вариантов в соответствии со значением аргумента
case "$VARiable" in
"$condition1" )
command...
;;
"$condition2" )
command...
;;
esac

Переменные в bash

Переменная в языке shell - это макрос, который может быть подставлен в строку команды перед её разбором. Оператор ${VAR} заменяется текстовой строкой, хранящейся в переменной с именем VAR. После подстановки значение переменной будет разбито на отдельные слова по пробельным символам. Если содержимое переменной должно интерпретироваться как одно слово, то оператор подстановки надо взять в кавычки "${VAR}"

Интерпретатор `bash` использует как минимум три типа переменных, отличающихся областью видимости:

A=BCD # Локальная переменная, доступная из данного скрипта
A=BCD cmd # Именованный параметр, передаваемый в окружение программы cmd не влияющий на текущий скрипт
export A=BCD # Глобальная переменная, видимая в текущем скрипте и в запускаемых программах

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

set – выдает список всех переменных с их значениями

VAR="string" - определяет локальную переменную интерпретатора и присваивает ей значение. Разделителями в команде являются символ = после имени переменной и первый пробел после значения. Пробелы вокруг знака равенства недопустимы. Пробел слева от знака равенства интерпретируется как часть имени, пробел справа – как пустая присваеваемая строка. Если строка содержит пробелы, то она должна быть заключена в кавычки.
$VAR – подстановка значения переменной VAR. При разборе строки именем переменной считается максимальная последовательность из букв, цифр и знаков подчеркивания.
${VAR} - то же что и $VAR позволяет избавиться от неоднозначности при разборе строки

export VAR делает переменную доступной для дочерних процессов (делает переменную глобальной)
export VAR=string допустимое объявление глобальной переменной
unset VAR уничтожает определение переменной

Пример экспорта переменной:
WORKDIR=/usr/src/linux
echo $WORKDIR #используем значение переменной
bash #запустили новую копию интерпретатора
echo $WORKDIR #переменная недоступна
exit # завершили копию интерпретатора
echo $WORKDIR #переменная снова доступна
export WORKDIR
bash
echo $WORKDIR #после экспорта переменная доступна запускаемым программам

Дополнительные возможности при работе с переменными

${VAR-default} - если VAR определена, то ее значение иначе значение default
${VAR=default} - если VAR определена, то ее значение иначе значение default и присваивание его VAR
${VAR?err_msg} - если VAR определена, то ее значение иначе печать err_msg
Пример подстановки вывода команды whoami в качестве значения по умолчанию:
echo ${username-`whoami`}

${#VAR} - длина значения переменной в символах
${#array[*]} или ${#array[@]} - размер массива (Массивы доступны в версии bash > 2)
${#*} или ${#@} число параметров скрипта

${VAR:pos} - подстрока с позиции pos
${VAR:pos:len} - подстрока с позиции pos длинной length

В следующих операциях Pattern это выражение в формате glob - * - любая последовательность символов, ? - один символ.

${VAR/Pattern/Replacement} - замена первого вхождения Pattern на Replacement, если Replacement отсутствует, то Pattern удаляется
${VAR//Pattern/Replacement} - глобальная замена
$(VAR#Pattern} - удаление минимальной строки, соответствующей Pattern в начале строки (удаление префикса)
$(VAR##Pattern} - удаление максимальной строки, соответствующей Pattern в начале строки
$(VAR%Pattern} - удаление минимальной строки, соответствующей Pattern в конце строки (удаление суффикса)
$(VAR%%Pattern} - удаление максимальной строки, соответствующей Pattern в конце строки

Пример:

VAR="file.test.txt"
echo ${VAR#file*.} => test.txt
echo ${VAR##file*.} => txt
echo ${VAR%.*} => file.test
echo ${VAR%%.*} => file

Спецсимволы в bash

Далее перечислены символы и синтаксические конструкции, имеющее особое значение в bash. Для ввода спецсимволов как они есть используют кавычки или спецсимвол \ отменяющий специальное значение следующего символа

\ Экранирование. Отменяет специальное значение следующего символа
\\ Символ "\"

# Комментарий, не работает в кавычках и в некоторых подстановках переменных и преобразовании основания чисел
echo "Это #не комментарий"
echo 'Это # не комментарий’
echo Это \# не комментарий
echo Это # Вот комментарий.
echo ${PATH#*:} #Специальная переменная
echo $(( 2#101011 )) #Преобразование системы счисления в арифметической подстановке.

>, >> - перенаправление стандартного вывода программы в файл
< - перенаправление стандартного ввода программы из файла
<<TERM перенаправление стандартного ввода программы из текста текущего скрипта со следующей строки до строки, состоящей из слова TERM.
|- перенаправление стандартного вывода программы на стандартный ввод другой программы

; Разделитель команд в строке
echo hello; echo there

;; Разделитель альтернатив в операторе case
case "$VARiable" in
abc) echo "$VARiable = abc" ;;
xyz) echo "$VARiable = xyz" ;;
esac

. Аналог команды source (#include в С++). Выполняет скрипт в текущем интерпретаторе.
. myconf

".." Двойные кавычки, отменяют действие спецсимволов кроме $ `..` и \

'...' Апострофы, отменяют действие всех спецсимволов в том числе и \, по этому нельзя включить апостроф в строку ограниченную апострофами

: Нулевая команда, всегда возвращает нулевой код ответа. В сочетании с перенаправлением ">" создает файл, или обнуляет существующий. В сочетании с перенаправлением ">>" создает файл, или изменяет время модификации существующего
:> data.xxx # File “data.xxx” now empty.
(можно и без двоеточия)

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

* Шаблон заменяющий любую последовательность символов
? Шаблон заменяющий ровно один символ
[xyz] Шаблон заменяющий один из перечисленных символов
{xxx,yyy,zzz,...} Подстановка одного из вариантов в шаблон. В скобках не должно быть неэкранированных пробелов
grep Linux file*.{txt,htm*} # Ищет слово “Linux” в файлах вида “fileA.txt”, “file2.txt”, “fileR.html”, “file-87.htm”, etc.

$ Подстановка значения переменной, арифметического выражения или стандартного вывода программы. Если значение содержит пробелы, то при подстановке оно разбивается на отдельные аргументы.
$A содержимое переменной A
$$ PID процесса
$? Код возврата из последней выполненной программы или функции, а также код возврата самого скрипта
$((2*2)) подстановка результата вычисления арифметического выражения
$(cmd) подстановка стандартного вывода программы
`...` тоже, что и $(...) – подстановка стандартного вывода программы

Пример: A=EE; echo $A $(echo QQ) $((7+5))
Результат: EE QQ 12
Ошибка: $A=ZZ
Результат: bash: EE=ZZ: command not found

(...) Группировка команд
(A=hello; echo $A)
Для выполнения группы в скобках запускается новый интерпретатор
A=123
(A=321)
echo A = $A # A = 123
# "A" внутри скобок – локальная переменная.

(...) Создание массива ( только в bash версии > 2)
Array=(element1 element2 element3)

[] Элемент массива ( только в bash версии > 2)
Array[1]=slot_1
echo ${Array[1]}

{1..10} - подстановка чисел от 1 до 10
{c..n} - подстановка символов от "c" до "n"

{...} Создание безымянной функции, удобно для перенаправления ввода/вывода нескольких команд в один файл. В отличие от настоящей функции видимости переменных не изменяется.
PACK=mysql
{
echo
echo "Archive Listing:"
rpm -qpl ${PACK} # Список фалов в пакете rpm
echo
rpm -i --test ${PACK} # Проверка, установлен ли пакет.
} > "${PACK}.txt" #И весь вывод в один файл.

[...] Встроенная функция test для вычисления логических выражений

((...)) Арифметическая подстановка, вычисляет арифметическое выражение в стиле языка Си внутри скобок

& - запуск программы в фоновом режиме
bash$ sleep 10 &
[1] 850
[1]+ Done sleep 10

Спецсимволы в командной строке

Каждая символ, введенный пользователем, обрабатывается драйвером терминала, а затем интерпретатором командной строки. В разных ОС набор спецсимволов может быть различным. Здесь описаны Linux и bash.

Управление процессами (обрабатываются драйвером терминала):
Ctrl D - символ конца файла при вводе с клавиатуры. Сообщает программе, что ввод закончился.
Ctrl C - отправка программе сигнала на завершение. Может быть проигнорировано.
Ctrl Z - перевод программы в фоновый режим без завершения. Работа с программой может быть продолжена после выполнения команды fg в bash.
Ctrl S/Ctrl Q- остановка/продолжение вывода программы на экран. Дублируется клавишей ScrLk.

Горячие клавиши bash:
Ctrl A – курсор в начало строки.
Ctrl E – курсор в конец строки.
TAB – автодополнение. Самая функциональная клавиша в bash. При вводе имени программы нажатие TAB приводит к поиску по первым введенным буквах всех программ в каталогах перечисленных в PATH. Если результат однозначный то производится подстановка, если нет, то повторное нажатие TAB приводит к выводу всех возможностей. При вводе параметров делается попытка завершить имя существующего файла по указанному пути (если в строке нет / то в текущем каталоге).
Ctrl P, Ctrl N (Стрелки вверх/вниз) – просмотр истории команд.
Ctrl R – поиск в истории команд, вводимые символы интерпретируются как уже выполнявшаяся команда. По мере нахождения соответствий делается подстановка. При нахождении нужного варианта можно нажать Enter для выполнения или Ctrl E для выхода из режима поиска в режим редактирования.
!! -выполнение предыдущей команды.
sudo !! -выполнение предыдущей команды через sudo.

Сокращения имен каталогов:
~ – домашний каталог пользователя
~– - предыдущий посещённый каталог
~+ – полное имя текущего каталога

Сокращение для предыдущего каталога позволяет удобно работать с двумя каталогами. Например
$cd ~/work
$cd /tmp
$cd ~-
$cd ~-
$echo ~+
/tmp

Список вопросов

+++++++++++++
Программа man форматирует и выдает в интерактивном режиме справочную информацию, например man cat выдает опции команды cat.
На сочетания клавиш ^C она не реагирует, ^D интерпретирует как PgDown. Как из неё выйти, не зная команды на выход?
+++++++++++++
Предположим, что в файле /etc/passwd есть запись
user123:x:10123:500:special user:/:/usr/bin/bc
Что сможет сделать пользователь user123, получив доступ через терминал?
+++++++++++++
Напишите команды, выполняющие следующие действия:

Выдать на экран слово «file»

Выдать на экран содержимое файла с именем «file»

Одной командой выдать на экран содержимое нескольких файлов «file1» «file2» «file3»

Одной командой выдать на экран содержимое всех файлов в каталоге /tmp имена которых начинаются с «file1»

Выбрать из вывода предыдущей команды все строки содержащие слово «make» и показать на экране последние четыре строки из отобранных
+++++++++++++++++++++++++++++
Как создать файл с именем «???»

Как удалить все файлы, имя которых имеет длину 3 символа и начинается с вопроса?

Как удалить в текущем каталоге все файлы и подкаталоги, имя которых начинается с точки?

Как удалить в текущем каталоге ВСЕ файлы и подкаталоги?

++++++++++++++++++++++++++++
Что выведут команды echo?

A='*'
echo "$A"

echo '$A'

echo $A

+++++++++++++
Что произойдёт при выполнении двух команд?
echo=qqq
echo $echo

Что произойдёт при выполнении двух команд?
A=echo
$A $A > $A

Судя по всему, bash выполняет перенаправление файлов до подстановки переменных. Исходя из этого, попытайтесь представить, что произойдёт в третьей команде
A=echo
O=’>’
$A $A $O $A
+++++++++++++++++++++++++++++++
Что произойдёт при выполнении команды?
ed file.txt <<EOF
1,\$s/a/b/g
w
q
EOF

+++++++++++++
Чем отличаются две команды в редакторе vi?
:!q

:q!
++++++++++++++++++++++++++++++++++
Что изменится после выполнения команды?
export PATH=$PATH:~/bin
+++++++++++++
Что напечатают программы (запущенные от обычного пользователя)?
touch /tmp/$$; echo $?; rm /tmp/$$

touch /$$; echo $?; rm /$$
++++++++++++++++++++++++++++++++
Арифметическое выражение в двойных скобках без знака $, например ((A=A-3)) ничего не подставляет в командную строку, но возвращает код завершения. Код равен 0 если результат не 0, код равен 1 если вычислен 0 или произошла ошибка
Что напечатают команды?
((1+2)) || echo $?

((A=1+2)) && echo $? && echo $A

+++++++++++++
Файл /etc/passwd состоит из строк, разбитых двоеточиями на поля. Формат такой
Логин:Пароль:uid:gid:комментарий:домашний каталог: командная строка
Предположим у на с есть пользователь user. Что выдаст команда?

ls $(grep user /etc/passwd| cut –d: -f6)
+++++++++++++
Какой вариант записи оператора самый правильный (пометить галочкой):
if grep qq file then echo success fi
if grep qq file; then echo success; fi
if grep qq file; then; echo success; fi
+++++++++++++
В каталоге находятся файлы с именами a1, a2…a9, b1,b2…b9. Напишите три варианта цикла for который бы выполнял бы какую-нибудь операцию (например grep qq) со всеми файлами с b2 по b6. Один вариант должен использовать подстановку {}, другой [], третий (()).
+++++++++++++
Почему команда выдаст Not Null?
A=0
if [ $A > 0 ]; then echo Not Null;fi
+++++++++++++
Напишите скрипт, который проверял бы, что имя является файлом и печатал соответствующий текст (/etc/passwd – файл, /etc - не файл)
++++++++++++
У программы ps есть ключ u (user) который добавляет имя пользователя в первую колонку списка процессов. У команды сортировки sort есть ключ –u (uniq, уникальный), который говорит, что повторяющие строки после сортировки отбрасываются. Выдайте список всех пользователей, у которых сейчас есть запущенные процессы.
+++++++++++++
Команда wc (word count – подсчёт слов) имеет ключи –c –w –l, которые указывают что надо подсчитать число символов, слов или строк соответственно.
Напишите команду, которая подсчитает число процессов запущенных пользователем с именем student
+++++++++++++
Большинство стандартных каталогов в Unix имеют владельца root группу root доступа и права rwxr-xr-x Объясните, зачем обычным пользователям даны два права x и r
+++++++++++++
Используя команды: wc –l (выдает число строк в файле file в формате 526<пробел>file), cut (или awk), head, tail и цикл for напишите скрипт, который выводит задом наперед (вначале последняя строка, потом предпоследняя и т.д) содержимое файла, имя которого находится в переменной $1. (Примечание. В Unix есть стандартная команда tac, которая выполняет нужное преобразование, но её использование будем считать неспортивным)
+++++++++++++
В CentOS Linux в файле /etc/init.d/functions есть такие строки
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_NORMAL="echo -en \\033[0;39m"
Предположите, что произойдёт, если выполнить скрипт
. /etc/init.d/functions
RES_COL=40; $MOVE_TO_COL; $SETCOLOR_SUCCESS OK; $SETCOLOR_NORMAL; echo
Зачем нужна точка в первой строке этого скрипта?
+++++++++++++
Тестовая программа test.c
#include "test.h"
int main() { return 0; }

Что неверно в таком запуске компилятора
gcc test.c jpeg.h

Какой файл будет создан при таком запуске компилятора
gcc –с test.c

Какие файлы будут использованы для сборки программы test при таком запуске
gcc –o test test.o -ljpeg
+++++++++++++
Программа sendmail использует для доставки почты файлы /etc/mail/mailertable и /etc/mail/virtusertable. Для ускорения доступа эти файлы программой makemap компилируются в двоичный вид - mailertable.db и virtusertable.db.

makemap hash <текстовый_файл> <скомпилированный_файл>

Напишите такой Makefile, чтобы после изменения текстовой версии любого из указанных файлов достаточно было перейти в /etc/mail/ и набрать make, для обновления скомпилированной версии.
+++++++++++

Инструментарий программиста в Linux: MAKE

make

Утилита автоматически определяет, какие части большой программы должны быть перекомпилированы и команды для их перекомпиляции. Наиболее часто make используется для компиляции C-программ и содержит особенности, ориентированные именно на такие задачи, но можно использовать make с любым языком программирования. Более того, применение утилиты make не ограничивается программами. Можно использовать еe для описания любой задачи, где некоторые файлы должны автоматически порождаться из других всегда, когда те изменяются.

make-file

Прежде чем использовать make, необходимо создать файл, называемый make-файлом, который описывает отношения между файлами Вашей программы и содержит команды для обновления каждого файла. Обычно исполняемый файл зависит от объектных файлов, которые, в свою очередь, зависят от исходных файлов и файлов заголовков. Для имени make-файла рекомендуется название  GNUmakefile, makefile или Makefile, причем поиск идет именно в указанном порядке. Если необходимо использовать нестандартное имя, то его можно передать явно через опцию -f.
Когда make-файл уже написан, достаточно выполнить в каталоге, где он находится, команду make. Простой make-файл состоит из правил (инструкций) следующего вида:

ПЕРЕМЕННАЯ = ЗНАЧЕНИЕ ... ЦЕЛЬ ... : ЗАВИСИМОСТЬ ...            КОМАНДА 1
           КОМАНДА 2 ПЕРЕМЕННАЯ = ЗНАЧЕНИЕ ... ЦЕЛЬ ... : ЗАВИСИМОСТЬ ...            КОМАНДА 1            КОМАНДА 2
и т.д.

ЦЕЛЬ обычно представляет собой имя файла, генерируемого программой make. Примерами целей являются исполняемые или объектные файлы. Цель может также быть именем выполняемого действия, как, например, clean.
ЗАВИСИМОСТЬ - это файл, изменение которого служит признаком необходимости цели. Часто цель зависит от нескольких файлов. КОМАНДА - это действие, которое выполняет make. Правило может иметь более чем одну команду - каждую на своей собственной строке. Важное замечание: необходимо начинать каждую строку, содержащую команды, с символа табуляции. Длинные строки разбиваются на несколько с использованием обратного слэша, за которым следует перевод строки. Знак диез # является началом комментария. Строка с # до конца игнорируется. Комментарии могут переноситься на несколько строк с помощью обратного слэша в конце строки.

Запуск make

Синтаксис:

make [Опции] [Переменная='abc'] [Цель]

Квадратные скобки означают необязательность присутствия данной части.
Цель - имя цели, которую надо выполнить.
Переменная ='abc' -переопределение переменных. Значения переменных, введенных в командной строке, имеют больший приоритет, чем определения в make-файле.
Опции:
-f file - явное задание имени make-файла, если задание опущено, то ищутся файлы GNUmakefile, makefile или Makefile.
-n - имитация действий без реального выполнения, служит для отладки.
-t - изменение времени модификации цели без реального выполнения.
-q - проверка на необходимость обновления цели без реального выполнения.

 

Более сложные способы применения MAKE

Правила написания Makefile

Порядок правил несущественен. По умолчанию главной целью make является цель первого правила в первом make-файле. Если в первом правиле есть несколько целей, то только первая цель берется в качестве цели по умолчанию. Цель, начинающаяся с точки, не используется как цель по умолчанию, если она не содержит  один или более символа '/' т.е. определяет путь к файлу; кроме того, по умолчанию не используются цели, определяющие шаблонные правила.
В качестве ЦЕЛИ или ЗАВИСИМОСТИ может использоваться список файлов через пробел или шаблон в стиле shell.
Шаблоны интерпретируются в момент выполнения правила, при присваивании переменным интерпретация шаблона не происходит, для присваивания списка файлов переменной используется специальная функция wildcard.


objects := $(wildcard *.o
edit: *.o
     cc -o edit *.o

Для автоматической генерации зависимостей от файлов заголовков в языке СИ можно использовать команду gcc -M file.c или gcc -MM file.c. Второй вариант не генерирует зависимости от системных заголовочных файлов. В КОМАНДАХ можно использовать автоматические переменные. Эти переменные имеют значения, заново вычисленные для каждого выполняемого правила на основе цели и зависимостей правила.

Автоматическая переменная Назначение
$@ Имя файла цели правила. В шаблонном правиле с несколькими целями,имя той цели, которая вызвала выполнение команд правила.
$< Имя первой зависимости. Если цель получила свои команды из неявного правила, то это будет первая зависимость, добавленная неявным правилом.
$? Имена всех зависимостей, которые являются более новыми, чем цель, с  пробелами между ними.
$^ Имена всех зависимостей, с пробелами между ними. Если Вы для цели неоднократно укажете одну и ту же зависимость, значение переменной '$^' будет содержать только одну копию ее имени.
$+ Эта переменная аналогична переменной '$^', только зависимости, указанные неоднократно дублируются в том порядке, в котором они указаны в make-файле. Это в первую очередь полезно для использования в командах компоновки, где является существенным повторение имен библиотек в определенном порядке
$* База с которой сопоставляется неявное правило (см. ниже). В шаблонном правиле база представляет собой часть имени файла, которая сопоставляется символу '%' в шаблоне цели. Если целью является файл 'dir/a.foo.b', а   шаблон цели - 'a.%.b', то базой будет 'dir/foo'. База полезна для создания имен файлов, связанных с правилом. В явных правилах база не определена как имя файла без расширения,если такое расширение можно выделить. Не рекомендуется использовать эту переменную в явных правилах

Неявные правила

Неявные правила определены для многих языков программирования и применяются в соответствии с расширением исходного файла. По умолчанию список расширений такой : .out, .a, .ln, .o, .c, .cc, .C, cpp, .p, .f, .F, .r, .y, .l, .s, .S, .mod, .sym, .def, .h, .info, .dvi, .tex, .texinfo, .texi, .txinfo, .w, .ch, .web, .sh, .elc, .el. При использовании неявных правил используются переменные, переопределяя которые можно управлять процессом преобразования файлов, например, указывать нестандартный компилятор или передавать ему опции.

Исходный файл Порожденный файл Команда
  Компиляция C-программ 'file.c' 'file.o' $(CC) -c $(CPPFLAGS) $(CFLAGS) file.c
  Компиляция программ на языке C++
'file.cc'
или 'file.C'
'file.o'  $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) file .cc
  Компиляция программ на Фортране
'file.f'
'file.o' $(FC) -c $(FFLAGS) file .f

 

Пример MakeFile

Пример makefile

Использование действий по умолчанию.

#default target - file edit
edit : main.o kbd.o command.o display.o \
        insert.o search.o files.o utils.o
         cc -o edit main.o kbd.o command.o display.o \
                    insert.o search.o files.o utils.o

main.o : main.c defs.h
        cc -c main.c
kbd.o : kbd.c defs.h command.h
        cc -c kbd.c
command.o : command.c defs.h command.h
        cc -c command.c
display.o : display.c defs.h buffer.h
        cc -c display.c
insert.o : insert.c defs.h buffer.h
        cc -c insert.c
search.o : search.c defs.h buffer.h
        cc -c search.c
files.o : files.c defs.h buffer.h command.h
        cc -c files.c
utils.o : utils.c defs.h
        cc -c utils.c
clean :
       rm edit main.o kbd.o command.o display.o \
          insert.o search.o files.o utils.o

По умолчанию, make начинает с первого правила (не считая правил, имена целей у которых начинаются с '.'). Это называется главной целью по умолчанию. В нашем случае это правило edit. Если файл edit новее чем объектные файлы, от которых он зависит, то ничего не произойдет. В противном случае, прежде чем make сможет полностью обработать это правило, он должен рекурсивно обработать правила для файлов, от которых зависит edit. Каждый из этих файлов обрабатывается в соответствии со своим собственным правилом. Перекомпиляция должна быть проведена, если исходный файл или любой из заголовочных файлов, упомянутых среди зависимостей, обновлен позднее, чем объектный файл, или если объектный файл не существует.
Правилу clean не соответствует никакого создаваемого файла и, соответственно, clean ни от чего не зависит и само не входит в список зависимостей. При запуске по умолчанию clean вызываться не будет. Для его выполнения необходимо явно указать цель при запуске make: make clean
Для сокращения записи можно использовать переменные и действия по умолчанию (неявные правила)

objects = main.o kbd.o command.o display.o \
          insert.o search.o files.o utils.o

edit : $(objects)
        cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
        -rm edit $(objects)

Переменная objects позволила использовать единожды написанный список объектных файлов, а для объектных файлов в make встроено неявное правило по умолчанию

file.c: file.o   cc -c file.c

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

objects = main.o kbd.o command.o display.o \
          insert.o search.o files.o utils.o

edit : $(objects)
       cc -o edit $(objects)

$(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h

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