Вы находитесь на странице: 1из 27

Лекция № 2

Командная оболочка Unix. Bash


Unix оболочка
• Unix оболочка — это интерпретатор командной строки, который выполняет команды, вводимые
пользователем. Мы вводим команду, она интерпретируется, выполняется а затем мы получаем
результат ее выполнения. Оболочка обеспечивает традиционный интерфейс ввода команд Unix,
к которому мы привыкли. Это, как правило, черный экран и белый текст. Мы вводим команды в
виде обычного текста, а также можем создавать скрипты из одной или нескольких команд.

• Оболочка — это ваш интерфейс взаимодействия с системой. После входа в систему Unix, вы
оказываетесь в программе, которая называется оболочка.

Виды оболочек:
• Thompson Shell
• PWB Shell
• Bourne Shell
• Almquist shell (ash)
• Bourne-Again Shell (Bash)
• Korn shell (ksh)
• Z shell (zsh)
• C shell
• Fish
История Unix оболочка
Манипулирование файловой
системой

• Манипулирование файлами:
ls, touch, cp, mv, rm
• Содержимое файлов:
cat, more, less, head, tail
• Манипулирование каталогами:
mkdir, rmdir, ls, cd, pwd
• Управление владельцами и правами:
chown, chgrp, chmod
• Создание ссылок: ln
• Поиск файлов: find, locate
• Узнать тип файла: file
Файловые маски
Bash поддерживает следующие файловые маски:
• *.срр — * заменяет любую последовательность
символов.
• lecture?.docx — ? заменяет один символ.
• lecture{1,2,3}.txt — {} подставляют значения,
заданные через запятую.
• lecture[1235].txt — [] совпадают с любым из
перечисленных символов. Поддерживаются
промежутки: [a-с], [2-­7].
Поток ввода/вывода
У каждого процесса есть три стандартных потока ввода/вывода:
stdin, stdout и stderr
Дескрипторы файлов stdin, stdout и stderr — 0, 1 и 2.

Потоки можно перенаправлять в файл и из файла:


$ll > list.txt
$grep –c test < list.txt

’>’ — перезаписывает файл, ’>>’ — дописывает в конец


Примеры
Перенаправить вывод random в null:
$cat /dev/random > /dev/null
По умолчанию ’>’ перенаправляет stdout:
$ls ­‐la > listing.txt
Перенаправление stderr в файл "error.txt“:
$ls­‐y 2> error.txt
Потоки можно перенаправлять друг в друга:
$ ls ­‐y >/dev/null 2>&1
’&>’ перенаправляет сразу stdout и stderr :
$grep test -‐r /etc &> results.txt
Потоки можно перенаправлять друг в друга:
$ls ­‐y >/dev/null 2>&1
Временный файл stdout другой программы:
$grep lecture* < (ll) > results.txt
Pipes
Pipe (конвеер) – это однонаправленный канал межпроцессного взаимодействия. Термин был
придуман Дугласом Макилроем для командной оболочки Unix и назван по аналогии с
трубопроводом. Конвейеры чаще всего используются в shell-скриптах для связи нескольких
команд путем перенаправления вывода одной команды (stdout) на вход (stdin) последующей,
используя символ конвеера ‘|’
Pipelines можно представить как:

Между программами происходит поточная


передача данных, т.е. следующая программа
не ждет полного завершения предыдущей
Pipes
Общий синтаксис:
command_1 | command_2 [| command_3 ...]
Примеры
Подсчет количества строк с словом “error” в файле log:
$grep -i “error” ./log | wc –l
Вывести отсортированные уникальные строчки из файла:
$ cat *.txt | sort | uniq > > result-file
Bash скрипты
Хороший тон:
• Скрипт выполняй только ту работу для которой был написан
• Желательно, что бы скрипт был переиспользуемым
• При работе скрипта обязательно выводить информационные сообщения

Перед тем как сесть писать новый скрипт будет полезно задать себе такие
вопросы:
• Какой источник данных?
• Как я буду хранить эту информацию?
• Нужно ли создавать какие-нибудь файлы? Где и скакими правами?
• Какие команды я буду использовать? На каких системах будет
использоваться мой скрипт? На всех ли системах должен
поддерживаются этот скрипт?
• Нужны ли пользователю какие-либо уведомления/сообщения? Почему
и когда?
Bash скрипты
Bash скрипт начинается с определения интерпретатора, т.е. bash:
#!/bin/bash
Зарезервированные слова:
break выход из цикла for, while или until
continue выполнение следующей итерации цикла for, while или until
echo вывод аргументов, разделенных пробелами, на стандартное устройство вывода
exit выход из оболочки
export отмечает аргументы как переменные для передачи в дочерние процессы в среде
hash запоминает полные имена путей команд, указанных в качестве аргументов, чтобы не
искать их при следующем обращении
kill посылает сигнал завершения процессу
pwd выводит текущий рабочий каталог
read читает строку из ввода оболочки и использует ее для присвоения значений указанным
переменным.
return заставляет функцию оболочки выйти с указанным значением
shift перемещает позиционные параметры налево
test вычисляет условное выражение
times выводит имя пользователя и системное время, использованное оболочкой и ее потомками
trap указывает команды, которые должны выполняться при получении оболочкой сигнала
unset вызывает уничтожение переменных оболочки
wait ждет выхода из дочернего процесса и сообщает выходное состояние.
Bash скрипты (Пример)
#!/bin/bash #указываем где у нас хранится bash-интерпретатор 
parametr1=$1 #присваиваем переменной parametr1 значение
первого параметра скрипта
script_name=$0 #присваиваем переменной script_name
значение имени скрипта
echo "Вы запустили скрипт с именем $script_name и параметром
$parametr1" # команда echo выводит определенную строку,
обращение к переменным осуществляется через
$имя_переменной.
echo 'Вы запустили скрипт с именем $script_name и параметром
$parametr1' # здесь мы видим другие кавычки, разница в том,
что в одинарных кавычках не происходит подстановки
переменных.
exit 0 #Выход с кодом 0 (удачное завершение работы скрипта)
Зарезервированные переменные Bash
$DIRSTACK - содержимое вершины стека каталогов
$EDITOR - текстовый редактор по умолчанию
$EUID - Эффективный UID. Если вы использовали программу su для выполнения команд от
другого пользователя, то эта переменная содержит UID этого пользователя, в то время как...
$UID - ...содержит реальный идентификатор, который устанавливается только при логине.
$FUNCNAME - имя текущей функции в скрипте.
$GROUPS - массив групп к которым принадлежит текущий пользователь
$HOME - домашний каталог пользователя
$HOSTNAME - ваш hostname
$HOSTTYPE - архитектура машины.
$LC_CTYPE - внутренняя переменная, котороя определяет кодировку символов
$OLDPWD - прежний рабочий каталог
$OSTYPE - тип ОС
$PATH - путь поиска программ
$PPID - идентификатор родительского процесса
$SECONDS - время работы скрипта(в сек.)
$# - общее количество параметров переданных скрипту
$* - все аргументы переданыне скрипту(выводятся в строку)
$@ - тоже самое, что и предыдущий, но параметры выводятся в столбик
$! - PID последнего запущенного в фоне процесса
$$ - PID самого скрипта
Условия
Структура if-then-else используется следующим образом:

if <команда или набор команд возвращающих код возврата(0 или 1)>


then
<если выражение после if истино, то выполняется этот блок>
else
<если выражение после if ложно, тот этот>
fi
В качестве команд возвращающих код возврата могут выступать структуры [[ , [ ,
test, (( )) или любая другая(или несколько) linux-команда.

test - используется для логического сравнения. после выражения, необходима


закрывающая скобка "]"
[ - синоним команды test
[[ - расширенная версия "[" (начиная с версии 2.02)(как в примере), внутри которой
могут быть использованы || (или), & (и). Должна иметь закрывающую скобку "]]"
(( )) - математическое сравнение
Условия
#!/bin/bash
source=$1 #в переменную source засовываем первый параметр скрипта
dest=$2 #в переменную dest засовываем второй параметр скрипта

if [[ "$source" -eq "$dest" ]] # в ковычках указываем имена переменных для


сравнения. -eq - логическое сравнение обозначающие "равны"
then # если они действительно равны, то
echo "Применик $dest и источник $source один и тот же файл!" #выводим
сообщение об ошибке, т.к. $source и $dest у нас равны
exit 1 # выходим с ошибкой (1 - код ошибки)
else # если же они не равны
cp $source $dest # то выполняем команду cp: копируем источник в приемник
echo "Удачное копирование!"
fi #обозначаем окончание условия.
Условия
Список логических операторв, которые используются для конструкции if-then-else-fi:

• -z # строка пуста
• -n # строка не пуста
• =, (==) # строки равны
• != # строки неравны
• -eq # равно
• -ne # неравно
• -lt,(< ) # меньше
• -le,(<=) # меньше или равно
• -gt,(>) #больше
• -ge,(>=) #больше или равно
• ! #отрицание логического выражения
• -a,(&&) #логическое «И»
• -o,(||) # логическое «ИЛИ»
Условия. Множественный выбор
Правила оформления оператора case:
1. Конструкция множественного выбора начинается с ключевого слова case.
2. Сразу за ключевым словом case, внутри кавычек, следует определение
входящего параметра. Чаще всего это значение переменной.
3. Начало определения блока сравнений открывается ключевым словом in,
расположенным за входящим параметром.
4. Каждое сравнение задается шаблоном. Он может быть строкой или числом,
а также содержать механизмы подстановки. Шаблон в обязательном
порядке закрывается правой круглой скобкой.
5. Сразу за правой круглой скобкой шаблона или на следующих строках после
него располагаются команды, требующие выполнения при совпадении
входящего параметра. Последняя команда внутри такого блока должна
завершаться двумя точками с запятой «;;».
6. Если вам требуется назначить несколько шаблонов для одного и того же
блока команд используйте символ «|» для их разделения. Например, «*.txt |
*.bat )».
7. Блок сравнений должен завершаться ключевым словом esac.
Условия. Множественный выбор (Пример)
#!/bin/bash

#считывание ввода пользователя


echo -n 'Ваша любимая компьютерная игра: '
read game

#осуществляем сравнения с шаблонами


case $game in
warcraft|wow)
echo "Жизнь за Нер'зула!!!«
;;
diablo)
echo 'Мы покроем себя славой‘
;;
sims)
echo 'Своеобразный выбор‘
;;
esac
Математические операции
Команда let производит арифметические операции над числами и
переменными.
#!/bin/bash $ ./bash2_primer2.sh
echo "Введите a: " Введите a:
read a 123
echo "Введите b: " Введите b:
read b 12
a+b= 135
let "c = a + b" #сложение a/b= 10
echo "a+b= $c" c после сдвига на 2 разряда: 40
let "c = a / b" #деление 123 / 12. остаток: 3
echo "a/b= $c"
let "c <<= 2" #сдвигает c на 2 разряда влево
echo "c после сдвига на 2 разряда: $c"
let "c = a % b" # находит остаток от деления
a на b
echo "$a / $b. остаток: $c "
Математические операции
+ — сложение
— — вычитание
* — умножение
/ — деление
** — возведение в степень
% — модуль(деление по модулю), остаток от деления

let позволяет использовать сокращения арифметических команд, тем


самым сокращая кол-во используемых переменных. Например: a = a+b
эквивалентно a +=b и т.д
Циклы for
Базовая структура циклов: Перебор сложных значений

for var in list #!/bin/bash


do for var in first "the second" "the third" "I’ll do
it”
команды do
done echo "This is: $var"
done

Перебор простых значений Инициализация цикла списком, полученным


из результатов работы команды
#!/bin/bash #!/bin/bash
for var in first second third fourth file="myfile"
do for var in $(cat $file)
echo The  $var item do
done echo " $var"
done
Циклы for (Разделители полей)
Oболочка bash считает разделителями полей следующие символы:

• Пробел
• Знак табуляции
• Знак перевода строки

Для того, чтобы изменить символ разделителя проблему, можно


временно изменить переменную среды IFS.

#!/bin/bash
file="/etc/passwd"
IFS=$'\n'
for var in $(cat $file)
do
echo " $var"
done
Циклы for в стиле C
Схема цикла при подобном подходе выглядит так:

for (( начальное значение переменной ; условие окончания цикла; изменение переменной ))

#!/bin/bash
for (( i=1; i <= 10; i++ ))
do
echo "number is $i"
done
Цикл while

Схема организации циклов while #!/bin/bash


while команда проверки условия var1=5
do while [ $var1 -gt 0 ]
другие команды do
done echo $var1
var1=$[ $var1 - 1 ]
done
Обработка вывода, выполняемого в цикле

#!/bin/bash
for (( a = 1; a < 10; a++ ))
do
echo "Number is $a"
done > myfile.txt
echo "finished."

Оболочка создаст файл myfile.txt и перенаправит в этот файл вывод


конструкции for.
Массивы
Задать массив:
Unix[0]='Debian'
Unix[1]='Red hat'
Unix[2]='Ubuntu'
Unix[3]='Suse'
Unix[4]='Fedora‘

Или:
declare -a Unix=('Debian' 'Red hat' ‘Ubuntu' 'Suse' 'Fedora');

Вывести длину массива или длину элемента ${#}:


echo ${#Unix[@]}
echo ${#Unix[3]}

Вывести последовательность из массива:


echo ${Unix[@]:1:3}