
lab2 / Лекция 2. Эффективная работа с командным
.pdf
КУРС: ИНТЕРПРЕТИРУЕМЫЕ ЯЗЫКИ ПРОГРАММИРОВАНИЯ
Лекция 2. Эффективная работа с командным интерпретатором Bash
Калашников Вячеслав Сергеевич
Старший преподаватель института ИнЭл, Начальник отдела развития САПР и перспективных разработок ООО ʺНМ-Техʺ, к.т.н.
vkalashnikov@nm-tech.org

СОДЕРЖАНИЕ
1. |
Разработка bash-скрипта (сценария) |
3 |
2. |
Команды интерпретатора bash: touch |
4 |
3. |
Работа со строками |
5 |
4. |
Регулярные выражения |
6 |
5. |
Утилиты обработки данных |
7 |
6. |
Перенаправление данных по потокам |
8 |
7. |
Применение конвейера |
9 |
8. |
Утилиты обработки текста sed и awk |
10 |
9. |
Базовые приемы работы с утилитой sed |
11 |
10. |
Базовые приемы работы с утилитой awk |
12 |
11. |
Использование подпрограмм |
13 |
12. |
Порядок вызова команд в bash |
14 |
13. |
Позиционные параметры командной строки |
15 |
14. |
Параметры и локальные переменные в функциях |
16 |
15. |
Опции командной строки |
17 |
16. |
Применение команды getopts |
18 |
17. |
Настройка окружения |
19 |
18. |
Встроенные переменные |
20 |
2 19. |
Рекомендации по разработке скриптов |
21 |

РАЗРАБОТКА bash-СКРИПТА (СЦЕНАРИЯ)
1) Создание файла “с нуля”:
$ touch script.sh
2) Наполнение скрипта командами:
echo ʺHello, world!ʺ
3) Запуск скрипта:
а) $ bash script.sh – указание командного интерпретатора в явном виде (наличие прав на исполнение необязательно) б) $ ./script.sh – запуск “по умолчанию” (пользователь должен иметь права на исполнение)
Рекомендации:
-первая строка скрипта всегда содержит директиву запуска оболочки (sha-bang): #!/bin/bash
-для скрипта установлены права на исполнение для соответствующих пользователей
|
Десятичное |
Символьное |
Двоичное |
|
|
|
|
|
0 |
- - - |
0 0 0 |
|
|
|
|
|
1 |
- - x |
0 0 1 |
|
|
|
|
|
2 |
- w - |
0 1 0 |
|
|
|
|
|
3 |
- w x |
0 1 1 |
|
|
|
|
|
4 |
r - - |
1 0 0 |
|
|
|
|
|
5 |
r – x |
1 0 1 |
|
|
|
|
3 |
6 |
r w - |
1 1 0 |
|
|
|
|
7 |
r w x |
1 1 1 |
Установка прав доступа для файла – команда chmod: Начальные права доступа для файла script.sh: -rw-r--r-- Добавить права на исполнение:
$ chmod +x script.sh => -rwxr-xr-x
Убрать права на исполнение:
$ chmod -x script.sh => -rw-r--r--
Добавить права на исполнения только для текущего пользователя: $ chmod u+x script.sh => -rwxr--r--
Установить права доступа на исполнение для текущего пользователя и группы: $ chmod 754 script.sh => -rwxr-xr--

КОМАНДЫ ИНТЕРПРЕТАТОРА bash: touch
touch [[-a] [-m] | [--time=timetype] [...]] [[-d datestring] | [-t timestamp]] [-c] [-h] [-r reffile] file [file ...]
Команда устанавливает время последнего обращения/изменения файла в текущее системное время или в заданное время. Альтернативное использование: создание нового пустого файла, если до вызова команды он отсутствовал (в случае, если не указана опция -c).
Более подробная информация о команде:
$ man touch
$ touch --help
В Linux для файлов существуют три типа “штампов” времени (timestamps):
▪atime (access time) – время последнего доступа к файлу (чтение)
▪mtime (modification time) – время последнего изменения содержимого файла (запись)
▪ctime (change time) – время изменения метаданных (изменился размер, права доступа, владелец)
Примеры использования:
$ touch -d "1 Feb" file1.txt
$ touch --date="1 |
February" file1.txt |
|||
$ touch |
-md |
"Sep 1 1927 |
23:58:59" file1.txt |
|
$ touch |
-cr |
a.txt |
b.txt |
|
4

РАБОТА СО СТРОКАМИ
$ echo $USER => user1
$ echo $USER_$HOSTNAME => ?
$ echo ${USER}_${HOSTNAME} => user1_srv5
Строковые операторы:
Символ |
Описание |
|
|
${var:-word} |
Если переменная var существует и не пустая, то |
|
возвращается ее значение, в противном случае |
|
возвращается word |
|
|
${var:=word} |
Если переменная var существует и не пустая, то |
|
возвращается ее значение, в противном случае ей |
|
присваивается значение word и оно же возвращается |
|
|
${var:?message} |
Если переменная var существует и не пустая, то |
|
возвращается ее значение, в противном случае выводится |
|
сообщение вида: var: message и текущая команда или |
|
скрипт завершает работу |
|
|
${var:+word} |
Если переменная var существует и не пустая, то |
|
возвращается word, в противном случае возвращается null |
|
|
${var:offset:length} |
Выполняет расширение подстроки. Возвращает подстроку |
|
переменной var, начиная с offset и длиной length |
|
символов (первый символ имеет позицию 0) |
|
|
5
Примеры использования:
$ echo ${username:-`whoami`} $ echo $username => null
$ echo ${username:=`whoami`} $ echo $username => <user>
$ echo ${username:?User is unknown} <user>
$ unset username
$ echo ${username:?User is unknown} username: User is unknown
$ a=${param1:+xyz} $ echo $a => null $ param2=1
$ a=${param2:+xyz} $ echo $a => xyz

РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ
Основные конструкции регулярных выражений:
Конструкция |
Значение |
|
|
? |
Любой единичный символ |
|
|
* |
Любая строка символов |
|
|
[<set>] |
Любой символ из указанного набора/множества |
|
|
[!<set>] |
Любой символ не входящий в указанный набор |
|
|
Примеры использования (текущий каталог содержит файлы lab1.sh test.tcl run.py run1.py lab2.sh):
$ ls lab?.sh lab1.sh lab2.sh $ ls *[0-9].*
lab1.sh lab2.sh run1.py $ ls *.??
?
Как вывести все имена файлов, кроме тех, что начинаются с “run” (run.py, run1.py) ?
$ ?
Примеры использования конструкции [<set>]:
Выражение |
Значение |
[abc] |
Символ a, b или c |
[.,;] |
Точка, запятая или точка с запятой |
[-_] |
Дефис или символ подчеркивания |
[a-c] |
Символ a, b или c |
[a-z] |
Любая буква в нижнем регистре |
[!0-9] |
Любой не цифровой символ |
[0-9!] |
Любая цифра или восклицательный знак |
[a-zA-Z] |
Любая буква в нижнем или верхнем регистре |
[a-zA-Z0-9_-] |
Любая буква, цифра, символ подчеркивания |
|
или дефис |
6

УТИЛИТЫ ОБРАБОТКИ ДАННЫХ
Наиболее популярные утилиты обработки/фильтрации данных:
Утилита |
Назначение, основная функция |
|
|
cat |
Копирует входные данные в стандартный вывод |
|
|
grep |
Осуществляет поиск строк в входных данных |
|
|
sort |
Сортирует строки в входных данных |
|
|
cut |
Извлекает части/секции строк из входных данных |
|
|
sed |
Выполняет операции редактирования в входных данных |
|
|
tr |
Транслирует символы в входных данных в другие символы |
|
|
Синтаксис команды cat: cat [опции] [<файл(ы)>]
Опция |
Назначение |
-n |
Нумеровать строки при выводе |
-b |
Нумеровать непустые строки |
-E |
Пометить концы строк символом $ |
-s |
Подавить многократный вывод пустых строк (выводится только одна) |
-T |
Отобразить символы табуляции как ^I |
-v |
Выводить непечатаемые символы |
7
Примеры использования утилит: $ cat file.txt
Строка 1 Строка 2
…
$ cat –n file.txt 1 Строка 1 2 Строка 2
…
$ cat
?
$ tac file.txt
?
$ tr a-z A-Z
?

ПЕРЕНАПРАВЛЕНИЕ ДАННЫХ ПО ПОТОКАМ
Основные операторы перенаправления данных:
Оператор |
Описание |
|
|
cmd1 | |
Канал; передает стандартный вывод команды cmd1 как |
cmd2 |
стандартный ввод для команды cmd2 |
|
|
>file |
Направляет стандартный вывод в file |
|
|
<file |
Принимает стандартный ввод из file |
|
|
>>file |
Направляет стандартный вывод в file; если file уже существует, |
|
данные добавляются к содержимому |
|
|
<>file |
Использовать file как стандартный ввод и стандартный вывод |
|
|
n<>file |
Использовать file как ввод и вывод для файла с дескриптором n |
|
|
n>file |
Направляет файл с дескриптором n в file |
|
|
n>>file |
Направляет файл с дескриптором n в file; если file уже |
|
существует, данные добавляются к содержимому |
|
|
n>& |
Дублирует стандартный вывод в файл с дескриптором n |
|
|
n>&m |
Вывод в файл с дескриптором n передается в файл с |
|
дескриптором m |
|
|
&>file |
Направляет стандартный вывод и стандартный вывод |
|
сообщений об ошибках в file |
|
|
8
Стандартные средства ввода/вывода: stdin (клавиатура), дескриптор 0 stdout (экран), дескриптор 1
stderr (вывод сообщений об ошибках на экран), дескриптор 2
Примеры использования:
$ echo Hello, world! > file.txt $ echo Hello, world! >> file.txt $ echo Hello, world! 1>file.txt $ exec 1>file.txt
$ echo Hello, world!
Перенаправление stdin с помощью exec: exec 6<&0
exec 0< text.txt i=1
while read line; do
printf "Line %2d : %s\n" $i $line let i=++i
done exec 0<&6

ПРИМЕНЕНИЕ КОНВЕЙЕРА
Конвейер (или канал) – это классический способ взаимодействия процессов, с помощью которого stdout одного процесса перенаправляется на stdin другого.
Типовое применение – совместно с командами вывода (cat, echo и др.), от которых поток данных поступает в "фильтр" (команда, которая на входе получает данные, преобразует их и обрабатывает).
Синтаксис команды grep:
grep [опции] <шаблон> [<файл>]
Опция |
Назначение |
|
|
-i |
Выполняет поиск без учета регистра символов |
|
|
-w |
Поиск совпадений целого слова |
|
|
-l |
Вывод только имен файлов, в которых найдены совпадения |
|
с шаблоном, без вывода самих совпадающих строк |
|
|
-r |
Рекурсивный поиск (включая все подкаталоги) |
|
|
-n |
Вывод номеров строк и самих строк, содержащих |
|
совпадения |
|
|
-v |
Вывод строк, не содержащих совпадения с шаблоном |
|
(инверсия) |
|
|
-с |
Подсчет числа совпадений без вывода самих строк |
|
(выводит число) |
9
Пример 1. Просмотреть на экране длинный список файлов $ ls –l | more
Пример 2. Вывести отсортированный список всех пользователей системы:
$ cut –d: -f1 /etc/passwd | sort
Примеры с командой grep:
$ cat circuit.log | grep "Simulation finished" $ cat file.txt | grep "^[0-9]"
$ cat run.log | grep –i "error"
$ grep pattern1 *.txt | grep -v pattern2 $ ls –l | grep user1
$ ps –ef | grep user1
$ ps –ef | grep symicade

УТИЛИТЫ ОБРАБОТКИ ТЕКСТА sed и awk
Утилиты Unix-систем для обработки текста:
sed – неинтерактивный редактор текстовых файлов
awk – язык обработки шаблонов с C-подобным синтаксисом
Основные общие свойства:
-Обладают схожим синтаксисом
-Работают с регулярными выражениями
-Читают данные из stdin (по умолчанию)
-Выводят результат обработки в stdout
-Наиболее эффективно выглядит комбинирование утилит с помощью конвейера (фактически достигается гибкость Perl)
Ключевое отличие: в случае с sed скрипт может легко передавать дополнительные аргументы утилите, в отличие от awk, с которой эта задача становится более затруднительной.
10