Технологический семинар: bash скрипты
DESCRIPTION
* “Одна задача – одна программа” * Создание скриптов * Основы программирования в Bash * Редакторы. Как выйти из VIM =)TRANSCRIPT
Лекция 3. Bash скрипты
www.compscicenter.ru 1
Толстиков Никита [email protected]
СS центр
26.02.2014
Манипулирование файловой системой
www.compscicenter.ru 2 26.02.2014
Манипулирование файлами: ls, touch, cp, mv, rm Содержимое файлов: cat, more, less, head, tail Манипулирование каталогами: mkdir, rmdir, ls, cd Управление владельцами и правами: chown, chgrp, chmod Создание ссылок: ln Поиск файлов: find, locate Узнать тип файла: file
Примеры:
www.compscicenter.ru 3 26.02.2014
Манипулирование файлами: $ touch file.txt $ chmod 700 file.txt $ cp file.txt newfile.txt $ rm file.txt $ mv newfile.txt file.txt
Манипулирование каталогами: $ pwd $ mkdir downloads $ cd downloads $ ls -‐la ../test $ cd -‐ $ rmdir downloads
Файловые маски
www.compscicenter.ru 4 26.02.2014
Bash поддерживает следующие файловые маски: • *.jpg — * заменяет любую последовательность символов. • lecture?.txt — ? заменяет один символ. • lecture{1,2,3}.txt — {} подставляют значения, заданные через запятую. • lecture[1235].txt — [] совпадают с любым из перечисленных символов. Поддерживаются промежутки: [a-‐с], [2-‐7].
Потока ввода/вывода
www.compscicenter.ru 5 26.02.2014
У каждого процесса есть три стандартных потока ввода/вывода: stdin, stdout и stderr Дескрипторы файлов stdin, stdout и stderr — 0, 1 и 2. Потоки можно перенаправлять в файл и из файла:
$ ls -‐lR > dir-‐tree.list $ grep test < dir-‐tree.list
·∙ ’>’ — перезаписывает файл, ’>>’ — дописывает в конец
Примеры
www.compscicenter.ru 6 26.02.2014
Перенаправить вывод random в null: $ cat /dev/random > /dev/null
По умолчанию ’>’ перенаправляет stdout: $ ls -‐la > listing.txt
Перенаправление stderr в файл "error.txt“: $ ls -‐y 2>error.txt
’&>’ перенаправляет сразу stdout и stderr: $ grep test -‐r /etc &>results.txt
Потоки можно перенаправлять друг в друга: $ ls -‐y >/dev/null 2>&1
Временный файл stdout другой программы: $ grep test <(ls –la) >results.txt
Pipes
www.compscicenter.ru 7 26.02.2014
Способ передачи вывода одной программы на вход другой, или в файл, или на принтер
Pipelines можно представить как:
Между программами происходит поточная передача данных, т.е. следующая программа не ждет полного завершения предыдущей
Общий синтаксис: command_1 | command_2 [| command_3 …]
Пример: $ dmesg | less
Примеры
www.compscicenter.ru 8 26.02.2014
Вывести отсортированные уникальные строчки из файла: $ cat *.txt | sort | uniq > result-‐file
Команда xargs переводит stdin в аргументы:
$ find . -‐name “*.txt” | xargs vi Используя back&ck(`) можно вывод команды послать на вход другой:
$ sudo chown `id -‐u` /somedir
Bash скрипты
www.compscicenter.ru 9 26.02.2014
Хороший тон: • Скрипт делает работу для которой написан • Скрипт делает ТОЛЬКО ту работу для которой написан • Желательно, что бы скрипт был переиспользуемым
Перед тем как сесть писать новый скрипт будет полезно задать себе эти вопросы :
• Какой источник данных? • Как я буду хранить эту информацию? • Нужно ли создавать какие-‐нибудь файлы? Где и скакими правами? • Какие команды я буду использовать? На каких системах будет использоваться мой скрипт? На всех ли системах поддерживаются эти системы? • Нужны ли пользователю какие-‐либо уведомления/сообщения? Почему и когда?
Bash скрипты
www.compscicenter.ru 10 26.02.2014
Bash скрипт начинается с определения интерпретатора, т.е. bash: #!/bin/bash
Зарезервированные слова и переменные: break выход из цикла for, while или unFl continue выполнение следующей итерации цикла for, while или unFl echo вывод аргументов, разделенных пробелами, на стандартное устройство вывода exit выход из оболочки export отмечает аргументы как переменные для передачи в дочерние процессы в среде hash запоминает полные имена путей команд, указанных в качестве аргументов, чтобы не искать их при следующем обращении kill посылает сигнал завершения процессу pwd выводит текущий рабочий каталог read читает строку из ввода оболочки и использует ее для присвоения значений указанным переменным. return заставляет функцию оболочки выйти с указанным значением shift перемещает позиционные параметры налево test вычисляет условное выражение times выводит имя пользователя и системное время, использованное оболочкой и ее потомками trap указывает команды, которые должны выполняться при получении оболочкой сигнала unset вызывает уничтожение переменных оболочки wait ждет выхода из дочернего процесса и сообщает выходное состояние.
Bash скрипты
www.compscicenter.ru 11 26.02.2014
Пример: #!/bin/bash #указываем где у нас хранится bash-‐интерпретатор parametr1=$1 #присваиваем переменной parametr1 значение первого
параметра скрипта script_name=$0 #присваиваем переменной script_name значение
имени скрипта echo "Cкрипт с именем $script_name и параметром $parametr1" # команда echo выводит определенную строку, обращение к переменным осуществляется через $имя_переменной. echo 'Cкрипт с именем $script_name и параметром $parametr1' # здесь мы видим другие кавычки, разница в том, что в одинарных кавычках не происходит подстановки переменных. exit 0 #Выход с кодом 0 (удачное завершение работы скрипта) Результат выполнения:
$./test.sh qwerty Cкрипт с именем ./test.sh и параметром qwerty Cкрипт с именем $script_name и параметром $parametr1
Bash скрипты
www.compscicenter.ru 12 26.02.2014
Пример: #!/bin/bash #указываем где у нас хранится bash-‐интерпретатор parametr1=$1 #присваиваем переменной parametr1 значение первого
параметра скрипта script_name=$0 #присваиваем переменной script_name значение
имени скрипта echo "Cкрипт с именем $script_name и параметром $parametr1" # команда echo выводит определенную строку, обращение к переменным осуществляется через $имя_переменной. echo 'Cкрипт с именем $script_name и параметром $parametr1' # здесь мы видим другие кавычки, разница в том, что в одинарных кавычках не происходит подстановки переменных. exit 0 #Выход с кодом 0 (удачное завершение работы скрипта) Результат выполнения:
$./test.sh qwerty Cкрипт с именем ./test.sh и параметром qwerty Cкрипт с именем $script_name и параметром $parametr1
Bash скрипты
www.compscicenter.ru 13 26.02.2014
Пример: #!/bin/bash #указываем где у нас хранится bash-‐интерпретатор parametr1=$1 #присваиваем переменной parametr1 значение первого
параметра скрипта script_name=$0 #присваиваем переменной script_name значение
имени скрипта echo "Cкрипт с именем $script_name и параметром $parametr1" # команда echo выводит определенную строку, обращение к переменным осуществляется через $имя_переменной. echo 'Cкрипт с именем $script_name и параметром $parametr1' # здесь мы видим другие кавычки, разница в том, что в одинарных кавычках не происходит подстановки переменных. exit 0 #Выход с кодом 0 (удачное завершение работы скрипта) Результат выполнения:
$./test.sh qwerty Cкрипт с именем ./test.sh и параметром qwerty Cкрипт с именем $script_name и параметром $parametr1
Bash скрипты
www.compscicenter.ru 14 26.02.2014
Зарезервированные переменные: $EDITOR -‐ текстовый редактор по умолчанию $EUID -‐ Эффективный UID. Если вы использовали программу su для выполнения команд от другого пользователя, то эта переменная содержит UID этого пользователя, в то время как... $UID -‐ ...содержит реальный идентификатор, который устанавливается только при логине. $GROUPS -‐ массив групп к которым принадлежит текущий пользователь $HOME -‐ домашний каталог пользователя $HOSTNAME -‐ ваш hostname $HOSTTYPE -‐ архитектура машины. $LC_CTYPE -‐ внутренняя переменная, котороя определяет кодировку символов $OLDPWD -‐ прежний рабочий каталог $OSTYPE -‐ тип ОС $PATH -‐ путь поиска программ $SECONDS -‐ время работы скрипта(в сек.) $# -‐ общее количество параметров переданных скрипту $* -‐ все аргументы переданыне скрипту(выводятся в строку) $@ -‐ тоже самое, что и предыдущий, но параметры выводятся в столбик $! -‐ PID последнего запущенного в фоне процесса $$ -‐ PID самого скрипта
Условия
www.compscicenter.ru 15 26.02.2014
Структура if-‐then-‐else: if <команда или набор команд возвращающих код возврата(0 или 1)> then <если выражение после if истино, то выполняется этот блок> else <если выражение после if ложно, тот этот> В качестве команд возвращающих код возврата могут выступать структуры и команды: test -‐ используется для логического сравнения. после выражения, необходима закрывающая скобка "]" [ -‐ синоним команды test [[ -‐ расширенная версия "[" (с версии 2.02, внутри которой могут быть использованы || (или), & (и). Должна иметь закрывающую скобку "]]" (( )) -‐ математическое сравнение.
Условия
www.compscicenter.ru 16 26.02.2014
Пример: if [[ "$source" -‐eq "$dest" ]] # в кавычках указываем имена переменных
для сравнения. -‐eq -‐ логическое сравнение обозначающие "равны"
then # если они действительно равны, то echo "Применик $dest и источник $source один и тот же файл!" #выводим сообщение об ошибке, т.к. $source и $dest у нас равны exit 1 # выходим с ошибкой (1 -‐ код ошибки) else # если же они не равны cp $source $dest # то выполняем команду cp: копируем источник в приемник echo "Удачное копирование!" fi #обозначаем окончание условия Результат выполнения:
$ ./primer2.sh 1 1 Применик 1 и источник 1 один и тот же файл! $ ./primer2.sh 1 2 Удачное копирование!
Условия
www.compscicenter.ru 17 26.02.2014
Логические операторы: -‐z #строка пуста -‐n #строка не пуста != #строки неравны -‐eq #равно -‐ne #неравно -‐lt,(< ) #меньше -‐le,(<=) #меньше или равно -‐gt,(>) #больше -‐ge,(>=) #больше или равно ! #отрицание логического выражения -‐a,(&&) #логическое «И» -‐o,(||) #логическое «ИЛИ»
Арифметические операции
www.compscicenter.ru 18 26.02.2014
Команда let производит арифметические операции над числами и переменными. Поддерживаемые операции:
+ — сложение — — вычитание * — умножение / — деление ** — возведение в степень % — модуль(деление по модулю), остаток от деления
Так же можно использовать составное присваивание, например +=
Арифметические операции
www.compscicenter.ru 19 26.02.2014
Пример: #!/bin/bash echo "Введите a: " read a echo "Введите b: " read b let "c = a + b" #сложение echo "a+b= $c" let "c = a / b" #деление echo "a/b= $c" let "c <<= 2" #сдвигает c на 2 разряда влево echo "c после сдвига на 2 разряда: $c" let "c = a % b" # находит остаток от деления a на b echo "$a / $b. остаток: $c "
Результат выполнения: $ ./bash2_primer2.sh Введите a: 123 Введите b: 12 a+b= 135 a/b= 10 c после сдвига на 2 разряда: 40 123 / 12. остаток: 3
Массивы
www.compscicenter.ru 20 26.02.2014
Задать массив: Unix[0]='Debian' Unix[1]='Red hat' Unix[2]='Ubuntu' Unix[3]='Suse' Unix[3]=‘Fedora'
Или: declare -‐a Unix=('Debian' 'Red hat' ‘Ubuntu' 'Suse' 'Fedora');
Вывести длину массива или длину элемента ${#}: echo ${#Unix[@]} echo ${#Unix[3]}
Вывести последовательность из массива: echo ${Unix[@]:1:3}
Массивы
www.compscicenter.ru 21 26.02.2014
Задать массив: Unix[0]='Debian' Unix[1]='Red hat' Unix[2]='Ubuntu' Unix[3]='Suse' Unix[3]=‘Fedora'
Или: declare -‐a Unix=('Debian' 'Red hat' ‘Ubuntu' 'Suse' 'Fedora');
Вывести длину массива или длину элемента ${#}: echo ${#Unix[@]} echo ${#Unix[3]}
Вывести последовательность из массива: echo ${Unix[@]:1:3}
Копировать массив и вставить в массив: Linux=(“${Unix}”) Linux=(“${Linux}”, ‘Mint’)
Циклы
www.compscicenter.ru 22 26.02.2014
Циклы: for <переменная> in <список>; do <команды>; done while <команда>; do <команды>; done until <команда>; do <команды>; done
Пример for: #!/bin/bash for i in 0 1 2 3 4 #переменной $i будем поочередно
присваивать значения от 0 до 4 включительно
do echo "Console number is $i“ #Пишем на консоль done #цикл окончен exit 0
Циклы
www.compscicenter.ru 23 26.02.2014
Пример while: #!/bin/bash again=yes #присваиваем значение "yes" переменной while [ "$again" = "yes" ] #Будем выполнять цикл, пока $again будет
равно "yes" do echo "Please enter a name:" read name echo "The name you entered is $name“ echo "Do you wish to continue?" read again done echo "Bye-‐Bye"
Vim
www.compscicenter.ru 24 26.02.2014
Как выйти из Vim?
Wikipedia: «В отличие от многих привычных редакторов, vi имеет модальный интерфейс. Это означает, что одни и те же клавиши в разных режимах работы выполняют разные действия.»
Способ 1:
ESC + :q! Или :q
Способ 2:
CTRL+Z $ kill %1
Самая полезная команда
www.compscicenter.ru 25 26.02.2014
Как вы думаете какая самая полезная команда?
Я думаю: man
Начните пользоваться man с команды: $ man man
Интересные ссылки
www.compscicenter.ru 26 26.02.2014
Частые ошибки программирования на Bash: • Часть 1: h�p://habrahabr.ru/post/47706/ • Часть 2: h�p://habrahabr.ru/post/47915/ • Часть 3: h�p://habrahabr.ru/post/48053/
Примеры написания скриптов: • Часть 1: h�p://habrahabr.ru/post/158971/ • Часть 2: h�p://habrahabr.ru/post/163691/
Распараллеливание процессов: h�p://habrahabr.ru/company/xakep/blog/210480/
10 Terminal Commands That Will Boost Your ProducFvity: h�p://code.tutsplus.com/arFcles/10-‐terminal-‐commands-‐that-‐will-‐boost-‐your-‐producFvity-‐-‐net-‐14105
Интересные скринкасты по теме(платные, но можно попробовать найти бесплатную ознакомительную версию):
h�ps://www.destroyallso¢ware.com/screencasts/catalog
25 Vim Tutorials, Screencasts, and Resources: h�p://code.tutsplus.com/arFcles/25-‐vim-‐tutorials-‐screencasts-‐and-‐resources-‐-‐net-‐14631
Спасибо за внимание
www.compscicenter.ru 27 26.02.2014