§ 3. Скрипты
Автоматически запускаемые скрипты
01 При каждом новом запуске оболочки в интерактивном режиме автоматически выполняются скрипты. Если оболочка запущена с флагом -l
, то выполняется скрипт ~/.bash_profile, иначе выполняется скрипт ~/.bashrc. Флаг -l
используется командой login
и обозначает первичный запуск оболочки при входе в систему, так что в файле ~/.bash_profile обычно пишут команды, которые нужно запустить только один раз. Также при завершении оболочки, запущенной с флагом -l
выполняются команды из файла ~/.bash_logout. Если вы хотите автоматически запускать команды из ~/.bashrc также при входе в систему, то внутри ~/.bash_profile нужно добавить команду для включения в него файла ~/.bashrc.
test -f ~/.bashrc && source ~/.bashrc
Эта команда проверит, что файл существует, и выполнит все команды из этого файла, как будто они были написаны внутри текущего файла.
Файл | Когда используется |
---|---|
~/.bash_profile | запуск bash -l |
~/.bash_logout | завершение bash -l |
~/.bashrc | запуск bash без -l |
02 Внутри автоматически запускаемых скриптов обычно пишут команды, упрощающие работу с оболочкой. Например, если вы храните свои вспомогательные скрипты в директории ~/.local/bin, то вы можете добавить ее в переменную PATH
, чтобы оболочка искала команды в этой директории наравне с системными директориями. Если вы замечаете, что постоянно набираете одни и те же флаги для какой-либо команды, то вы можете сделать для нее псевдоним с помощью команды alias
, в котором укажете эти флаги. Тогда в интерактивном режиме они всегда будут добавляться к вашей команде. Также в bash
можно настраивать внутренние опции посредством переменных.
Отладка скриптов
03 Из-за сложных правил обработки пробелов и кавычек сложно понять, как произошла ошибка. Для решения этой проблемы обычно в начало скрипта добавляют опцию set -x
. После включения этой опции оболочка будет выводить каждую команду, которую она запускает со списком фактических аргументов (с раскрытыми подстановками переменных и т.п.). Также для скриптов полезна опция set -e
, которая остановит выполнение скрипта, как только какая-либо команда вернет ненулевое значение.
04 Для проверки корректности работы с подстановками и корректности использования стандарта POSIX sh, существует команда и веб-сервис shellcheck
. Ниже показан пример работы команды на одном из скриптов.
$ cat my-script #!/bin/sh for i in 1 2 3; do echo "$i" "$x"; done $ shellcheck my-script In my-script line 2: for i in 1 2 3; do echo "$i" "$x"; done ^-- SC2154: x is referenced but not assigned. For more information: https://www.shellcheck.net/wiki/SC2154 -- x is referenced but not assigned.
Функции
05 Внутри скриптов можно создавать функции, которые ведут себя как встроенные скрипты: внутри них переопределяются переменные-аргументы $1
, $2
и так далее, а вместо exit
используется return
. Функции удобно в больших скриптах, где вы хотите избежать повторения кода или хотите сгруппировать код в логические единицы.
hello() { echo "Hello $1" } hello "X" # выведет Hello X
Генерация потока ввода
06 Многие команды работают со стандартным потоком ввода, но не с аргументами, из-за чего возникает необходимость использовать подстановки переменных внутри потока ввода. Для этого используются генераторы потока ввода, которые по английски называются here-strings. Они также удобны для генерации конфигурационных и иных файлов.
x=1 y=2 # подстановка разрешена, получится файл # x = 1 # y = 2 cat > my.conf << EOF x = $x y = $y EOF # подстановка не разрешена, получится файл # x = 1 # y = 2 cat > my.conf << EOF x = $x y = $y EOF
Задания
Открытие файлов 1 балл
07 Напишите скрипт под названием open, который открывает файл в подходящей программе. Программа выбирается на основе MIME-типа файла. Этот тип определяется с помощью команды file
, и вам нужно найти подходящий для этого флаг в документации. Затем для открытия файла используется программа, которая умеет работать с такими типами файлов: gimp
, libreoffice
, mpv
. Тестовые файлы можно скачать здесь. Если вы делаете задание на сервере, то вместо запуска программы выведите нужную для запуска команду. Для выбора программы используйте условные переходы (case
или if
).
Аргументы 1 балл
08 Напишите скрипт, который принимает опции -x
, -y
и выводит погоду в точке с долготой X и широтой Y. Для определения погоды, используйте сайт wttr.in. Для обработки аргументов используйте встроенную функцию getopts
(не перепутайте ее с getopt
). Пример использования этой функции ниже.
# двоеточие после опции обозначает, что у нее есть значение, а не просто вкл./выкл. while getopts a:b: option do case "$option" in a echo "a=$OPTARG" ;; b) echo "b=$OPTARG" ;; *) echo "no options" ;; esac done
Функции 1 балл
09 Напишите функцию, которая запускает переданную в нее команду и перенаправляет стандартный поток вывода и поток ошибок в файл. Название файла передается в качестве первого аргумента, остальные аргументы — это команда. Пример вызова ниже.
my_func /tmp/my-output ls -l
Генерация файлов 2 балла
10 Напишите скрипт, который генерирует еще один скрипт, который переименовывает все файлы в директории, меняя регистр на прописные буквы. Для генерации скрипта используйте генерацию потока ввода. Для изменения регистра используйте команду tr
. Для переименования файлов используйте команду mv
. Список файлов должен вставляться в скрипт с помощью подстановки во время генерации потока ввода. Пример результирующего скрипта показан ниже. Вам может пригодиться перенаправление потока вывода, которое не добавляет данные в конец файла, а не перезаписывает его. Оно реализуется с помощью символов >>
.
mv x X mv y Y mv z Z