Вячеслав Ткачев
BASH. Справочное пособие
Глава1. Оболочка общие сведения.
В процессе загрузки операционных систем семейства Linux, после загрузки ядра системы выполняется переход в интерактивный режим – режим взаимодействия пользователя и операционной системы. В ОС Linux, первым запускаемым в ходе загрузки процессом, является программа инициализации init, которая определяет перечень и характеристики терминалов, имеющихся в системе, и вызывает программу интерактивного входа getty, отображающую приглашение для ввода имени пользователя. После ввода имени пользователя и пароля, программа getty вызывает программу login, которая проверяет достоверность учетной записи, выполняет переход в домашний каталог пользователя и передает управление программе начального запуска сеанса, в качестве которой обычно используется программа оболочки пользователя, конкретная разновидность которой определяется содержимым файла /etc/passwd для данной учетной записи.Командная оболочка (shell) обеспечивает взаимодействие между пользователем и средой операционной системы Linux. Она является специализированным программным продуктом, который обеспечивает выполнение команд и получения результатов их выполнения, или, если совсем уж упрощенно, оболочка – это программа, которая предназначена для обеспечения выполнения других программ по желанию пользователя. Примером оболочки может быть, например, интерпретатор команд command.com операционной системы MS DOS, или оболочка bash операционных систем Unix / Linux. Оболочка Bash представляет средства для написания сценариев оболочки.
Оболочка читает свой ввод ....
Оболочка разбивает входные данные на токены:
слова и операторы.
Оболочка анализирует ввод в простые и составные
команды.
Оболочка выполняет различные расширения (отдельно) …
Оболочка выполняет перенаправление и удаляет
операторы перенаправления и их операнды из
списка параметров.
Оболочка выполняет функцию, встроенный,
исполняемый файл или скрипт …
Оболочка по желанию ожидает завершения
команды и собирает статус выхода.
1.1 Краткий обзор функциональных средства.
В оболочке Bash предоставляются следующие функциональные средства и возможности
Переадресация ввода-вывода.
Применение метасимволов для сокращения имен файлов. Переменные и параметры для специальной настройки рабочей среды. Встроенный набор команд для написания программ оболочки. Функции и оболочки для модульной организации задач.
Управление заданиями.
Редактирование (редакторы vi ,Emacs).
Доступ к предыдущим командам.
Арифметические операции.
Массивы и арифметические выражения.
Применение псевдонимов и другие средства.
1.2 Вызов оболочки.
Интерпретатор команд оболочки можно вызвать
bash [параметры ][аргументы ]
Путь к оболочке по ссылке /bin/sh.
Команды оболочки можно выполнять с терминала, из файла (когда в качестве первого аргумента указан сценарий).Исходные оболочки читают содержимое файлов etc/profile и . profile profile
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), …).
if [ "${PS1-}" ]; then
if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ];
Примечание
$ echo $PS1-
${debian_chroot:+($debian_chroot)}\u@\h:\w\$ -
$ echo $BASH-
/bin/bash-
$ echo $BASH
/bin/bash
then
# The file bash.bashrc already sets the default PS1.
# PS1='\h:\w\$ '
if [ -f /etc/bash.bashrc ]; then
. /etc/bash.bashrc
fi
else
Следующий фрагмент кода определяет форму приглашения для root # для user $
if [ "`id -u`" -eq 0 ]; then
PS1='# '
else
PS1='$ '
fi
fi
fi
Следующий фрагмент кода запускает один за другим всескрипты в каталоге /etc/profile.d
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
Глава 2 Синтаксис.
2.1.Специальные файлы.
Оболочка читает содержимое одного или нескольких файлов запуска.
/etc/profile Автоматически при входе в систему
~/.bash_profile, ~/.bash_login или ~/.profile
~/.bashrc
~/.bash_logout Выход из системы или команда exit,
2.2 Метасимволы подстановки имен файлов.
* Совпадение с любой строкой.
Пример, перечислить файлы начинающие с output
$ ls output*
output1.wav output2.wav output3.wav output4.wav
? Совпадение с любым символом.
Пример
$ cd video?
~/video1$
[ abc..] совпадение с любым символом в квадратных скобках.
[!abc..] совпадение с любым символом кроме указанных в квадратных скобках.
~ Начальный каталог текущего пльзователя
~max Начальный каталог пользователя max
~+Текущий рабочий каталог ($PWD)
~– Предыдущий рабочий каталог ($OLDPWD).
Пример
~/video1$ cd # Переходим в текущий каталог.
$ cd – # Переходим из текущего каталога в предыдущий.
~/video1$
2.3.Метасимволы при установленном параметре extglob.
Активизировать расширение шаблонов командой
shopt (манипулирование параметрами оболочки).
shopt: shopt [-pqsu] [-o] [параметр …]
Set and unset shell options.
Options:
–o restrict OPTNAMEs to those defined for use
with `set -o'
–p print each shell option with an indication
of its status
–q suppress output (запретить выход).
–s enable (set) each OPTNAME
–u disable (unset) each OPTNAME
$shopt -s extglob
$ man shopt
Нет справочной страницы для shopt
?(шаблон) Совпадение с нулевым или единичным
количеством экземпляров заданного шаблона.
*(шаблон) Совпадение с нулевым или большим
количеством экземпляров заданного шаблона.
+(шаблон)Совпадение с единичным или большим
количеством экземпляров заданного шаблона.
@(шаблон) Точное совпадение с одним экземпляром
заданного шаблона.
! (шаблон) Совпадение с любыми символьными
строками не совпадающими с заданным шаблоном
Пример 1 Создадим файл из одной строки
$ cat >fs2.txt
Hello
^d
$ rm fs?(2).txt; cat fs2.txt
cat: fs2.txt: Нет такого файла или каталога
Пример 2
$ cat >fs01.txt
Allo
$ rm fs*(01).txt; cat fs01.txt
cat: fs01.txt: Нет такого файла или каталога
Пример 3
$ cat >fs_lin.txt
Hello friend
$ rm fs@(_lin).txt; cat fs_lin.txt
cat: fs_lin.txt: Нет такого файла или каталога
Пример 4
$ cat >fs_lin.txt
Hello friend
$ rm fs!(lin).txt; cat fs_lin.txt
rm: невозможно удалить 'fs!(lin).txt': Нет такого файла или каталога
cat: fs_lin.txt: Нет такого файла или каталога
2.4 Совпадение с классами символов.
Класс Совпадающие символы
alnum Буквенно-цифровые
alpha Буквенные
ascii Символы в коде ACII
blank Пробелы и знаки табуляции
cntrl Управляющие
digit Десятичные цифры
graph Непробельные
lower Строчные буквы
print Печатаемые
punct Знаки препинания
space Пробельные
upper Прописные буквы
word То же что и alnum
xdigit Шестнадцатиричные цифры
Пример
Эквивалентом выражения "[a-zA-Z_0-9]" является выражение "[[:alnum:]]"
Выражению "[0-9]" эквивалентно выражение "[[:digit:]]"
Выражению "[a-Z]" эквивалентно регулярное выражение "[[:alpha:]
[01[:alpha:]%] совпадает с 0 ,1 ,любым алфавитным символом или %.
2.5 Раскрытие скобок.
Раскрытие скобок выполняется прежде других видов раскрытия выражений, {} не должны заключаться в кавычки. Подстановка команд при раскрытии скобок игнорируется оболочкой BASH.
Пример 1
$ echo hi{BBB,AAA}there
hiBBBthere,hiAAAthere
Пример2
$ echo a{d,c,b}e
ade ace abe
Пример 3
$ echo 1 to 5 is {1..5}
1 to 5 is 1 2 3 4 5
$ echo 1 to 8 by 2 {1..8}
1 to 8 by 2 1 2 3 4 5 6 7 8
Использование скобок ( ) показано на следующем примере – выполнение группы команд.
$ (date; w;) Результат
Чт 22 июл 2021 08:31:12 MSK
08:31:12 up 3:00, 1 user, load average: 0,02, 0,14, 0,18
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
max tty2 tty2 05:31 2:59m 0.11s 0.10s /usr/libexec/gn
Использование скобок [ ] и (( )) показано на примере простого скрипта.
$ cat >skobki.sh
#!/bin/bash
X=1
while [ $X -lt 5 ]
do
echo "–> $X <–"
X=$(( $X+1 ))
done
exit 0
$ chmod +x skobki.sh
$ ./skobki.sh
–-> 1 <–
–-> 2 <–
–-> 3 <–
–-> 4 <–
2.6 Управляющие последовательности символов.
Распознаются и интерпретируются в следующих контекстах. Символьная строка в форме $ '…'
Аргументы в командах echo -e , printf %b
(Подставить управляющие последовательности символов в символьные строки).
Форматирующие строки, указываемые в команде printf ( управляющие последовательности символов в заданном формате экранируются).
\a Звонок
\b Возврат на 1 позицию
\c Подавить знак новой строки
\e Переход
\E Переход
\f Перевод страницы
\n Перевод строки
\r Возврат каретки
\t Табуляция
\uHHHH Символ HHHH в Юникоде
\nnn Восьмиричное значение nnn
\’ Одиночная кавычка
\” Двойная кавычка
\? Знак вопроса
\\ Обратная косая черта
Простой пример
$ echo -e "Hello Friend"
Hello Friend
$ echo -e "Hello\nFriend"
Hello
Friend
$ echo -e "Hello Friend" \?
Hello Friend ?
2.7 Формы команд.
–Выполнить команду в фоновом режиме $ cmd &.
–Выполнить команды группой в текущей оболочке {cmd1; cmd2}.
Пример 1
$ { who;pwd; }
max tty7 2019-08-12 05:17 (:0)
/home/max
–Выполнить команды в подоболочке (cmd1 ;cmd2)
Пример 2
$ (date; who; pwd) > logfile
$ cat logfile
Сб авг 3 09:03:21 MSK 2019
max tty7 2019-08-03 08:23 (:0)
/home/max
–Передать выход cmd1 на вход cmd2. $ cmd1 | cmd2
Пример 3, найти все файлы с расширением .sh и
сделать их исполняемыми
$ find *.sh -type f |xargs chmod +x
Проверка
$ ls -l *.sh
–Результат команды cmd2 как аргумент cmd1.
$ cmd1 `cmd2`
$ cat `pwd`
cat: /home/max: Это каталог
–Подстановка команд сmd1 $(cmd2)
Пример 4, создадим файл с датой
$ touch f01 $(date)
$ ls -l f01
–rw-rw-r– 1 max max 0 авг 3 09:39 f01
Числовой результат в качестве аргумента
cmd $ (выражение)
–Логическое И. $ cmd1 && cmd2
–Логическое ИЛИ $ cmd1 || cmd2
–Логическое НЕ $!cmd
Пример 5
$ date || touch f81.txt; ls f81.txt
Сб 30 мая 2020 06:43:33 MSK
ls: невозможно получить доступ к 'f81.txt': Нет такого файла или каталога
$ date && touch f81.txt; ls f81.txt
Сб 30 мая 2020 06:43:54 MSK
f81.txt
2.8 Простая переадресация ввода-вывода.
Ниже отображены формы переадресации ввода-вывода
cmd>file Направить результат команды в файл.
Пример 1
$ date >f30.txt; cat f30.txt
Вт июн 11 22:10:14 MSK 2019
cmd>> file Добавить результат команды в файл
Пример 2
$ date >>f30.txt; cat f30.txt
Вт июн 11 22:10:14 MSK 2019
Вт июн 11 22:11:45 MSK 2019
cmd файла. Пример 3 $ cat Вт июн 11 22:10:14 MSK 2019 Вт июн 11 22:11:45 MSK 2019 Пример 4 Встраиваемая строка. Представить текст заданного слова в качестве входных данных для указанной команды. $ cat <<<"Privet" Privet Пример 5 cmd <>file Записать в файл результат команды, содержимое файла не нарушается. $ date <> f30.txt; cat f30.txt Вт июн 11 21:58:17 MSK 2019 Вт июн 11 17:15:49 MSK 2019 cmd >| file Направить результат команды в файл переписав его содержимое. Пример 5 Направить результаты в файл, переписав его содержимое. $ date Пн 12 июл 2021 08:02:24 MSK $ cat >f30.txt Hello $ date >| f30.txt $ cat f30.txt Пн 12 июл 2021 08:03:13 MSK 2.9 Переадресация ввода-вывода с использованием дескрипторов файлов. Файловый дескриптор – целое число,которое указывает доступ к файлу. Стандартный ввод stdin дескриптор 0. Стандартный вывод stdout дескриптор 1. Стандартный вывод ошибок stderr дескриптор 2. Клавиатура stdin файл. Экран stdout файл. Файловый дескриптор привязан к индефикатору процесса. Пример # sleep 1000 & [2] 5021 # cd /proc/5021/fd ; ls 0 1 2 cmd >&n Направить результат команды в файл с дескриптором n. Пример 1 # дескриптор 1 стандартный вывод. $ date >&1 Вт июн 11 22:05:51 MSK 2019 cmd >&– Закрыть стандартный вывод $ date >&- date: ошибка записи: Неправильный дескриптор файла. cmd<&n Взять входные данные для указанной команды из файла с заданным дескриптором n. $ cat >file1<&0 privet $ cat file1 privet cmdm<&n Входные данные из файла с дескриптором m поступают из файла с дескриптором n. $ cat >file1 2<&0 privet 4 # Набираем с клавиатуры $ cat file1 privet 4 cmd<&– Закрыть стандартный ввод. $ pwd<&- /home/max1 $ cmd<&n Направить содержимое файла с заданным дескриптором n в стандартный ввод,получив сначала копию, а затем закрыв оригинал. cmd>&n- Направить содержимое файла с заданным дескриптором n в стандартный вывод,получив сначала копию,а затем закрыв оригинал. Пример Напишем следующий скрипт $ cat f2.sh #!/bin/sh read str <&0 echo "$str" | festival –tts –language russian Запускаем скрипт $ sh f2.sh Набираем в терминале фразу Привет друзья. Нажимаем Enter и слышим «Привет друзья» Пример 2 $ cat f5.txt Hello my friend $ read str Hello my friend Использование команды exec с дескрипторами. exec 0 Создадим под root myfile с двумя командами. # cat >myfile pwd; date Выполнить команды из файла вместо стандартного ввода. # exec 0 # pwd; date /root exec 1 cat myscript1.sh #!/bin/sh exec 1>outfile 0echo "This a test" $ cat ./outfile This is a test exec 3 $ cat myscript3.sh #!/bin/sh exec 3> myfile echo "Privet" >&3 cat ./myfile $sh myscript.sh Privet Примечание возможно использование команды exec c дескрипторами 0-9. 2.10 Многократная переадресация ввода-вывода. Направить стандартный вывод ошибок в заданный файл cmd 2>file Пример 1 $ ls -l /root/ 2>ls_er; cat ls_er ls: невозможно открыть каталог '/root/': Отказано в доступе. Направить стандартный вывод ошибок и данных в заданный файл. cmd >file 2>&1 Пример 2 $ ls -l f1.txt; ls -l /root/ 2>&1 >ls1 –rw-rw-r– 1 max1 max1 6 мая 9 07:21 f1.txt ls: невозможно открыть каталог '/root/': Отказано в доступе. $ cat ls1 ls: невозможно открыть каталог '/root/': Отказано в доступе. Присоединить стандартный вывод данных и ошибок к содержимому данного файла cmd&>> file Пример 3 $ ls -l f1.txt; ls -l /root/ &>> ls2 –rw-rw-r– 1 max1 max1 6 мая 9 07:21 f1.txt $ ls -l f1.txt; ls -l /root/ &>> ls2 –rw-rw-r– 1 max1 max1 6 мая 9 07:21 f1.txt max1@hp:~$ cat ls2 ls: невозможно открыть каталог '/root/': Отказано в доступе. ls: невозможно открыть каталог '/root/': Отказано в доступе. Направить стандартный данных в заданный file1, стандартный вывод ошибок в указанный file2 Направить стандартный вывод данных и ошибок в стандартный вывод, так и в заданные файлы. сmd 2 >&1 |tee файлы или cmd |& tee файлы Пример 4 $ pwd; ls -l /root/ 2>&1 |tee ls3 /home/max1 ls: невозможно открыть каталог '/root/': Отказано в доступе. $ cat ls3 ls: невозможно открыть каталог '/root/':Отказано в доступе. 2.11 Сохранение дескрипторов файлов в переменных. Допускается указывать имя переменной вместо числового обозначения дескриптора. Пример. Нахождение дескриптора файла. $ exec 4>file;echo "OK">&4; cat ./file OK max@hp:/dev/fd$ ls 0 1 2 255 4 max@hp:/dev/fd$ cat 4 OK Пример использования дескрипторов числом более 9 $ mv f1.txt f1 $ echo f1 {f1fd}>xyz f1 $ echo $f1fd 11 $ cd /dev/fd max@hp:/dev/fd$ ls 0 1 11 2 255 4 max@hp:/dev/fd$ echo "Privet">&11 max@hp:/dev/fd$ cat 11 Privet Дескриптор файла,сохраненный в переменной оболочки может быть использован в сценарии. 2.12 Специальные имена файлов. /dev/stdin Дубликат дескриптора файла 0 /dev/stdout Дубликат дескриптора файла 1 /dev/stderr Дубликат дескриптора файла 2 /dev/fd/ /dev/tcp/ Оболочка Bash устанавливает соединение с указанным хостом через заданный порт, используя полученный в итоге дескриптор файла при переадресации ввода-вывода. ~/Документы$ find -print >filelist 2>no_access Обнаруживаемые файлы направляются в файл filelist, а сообщения об ошибках в файл no_access Проверка ~/Документы$ cat filelist . ./Posix1.doc ./script ./script/sc01.sh ./no_access # новый файл ./rus2.doc ./filelist # новый файл ./otchet.doc Глава 3.Функции. Функция совокупность команд, выполняемых в сценарии оболочки. Синтаксис функции – имя (){ код-тело функции } [ виды переадресации] Обращение к функции происходит по имени. При выполнении функции не создается нового процесса. Она выполняется в среде соответствующего процесса. Аргументы функции становятся ее позиционными параметрами; имя функции – ее нулевой параметр. Прервать выполнение функции можно оператором "return [n]", где (необязательное) "n" – код возврата. Функции вызываются таким же образом, как и команды. Если используется ключевое слово function,то указывать () после имен необязательно Пример создания простой функции с именем privet. $ if [ "$USER"=max ]; then > privet ( ) { > echo "Privet Max";} > fi Запускаем функцию $ privet Результат Privet Max Характерно что функцию можно запускать многократно, результат будет тот же. Функция в скрипте. Функция fatal -выдать сообщение о неисправимой ошибке и прервать исполнение. Пример 2 Создадим простой скрипт c функцией fatal. $ cat >func1.sh #!/bin/sh fatal () { echo "$0: fatal error:" "$@" >&2 exit 1 } if [ $# = 0 ] then fatal not enough arguments fi Проверка $ sh func1.sh func1.sh: fatal error: not enough arguments Пример 3 $ cat >myscript.sh #!/bin/bash function myfunc { read -p "Enter a value: " value echo "adding value" return $(( $value + 10 )) } myfunc echo "The new value is $?" Запускаем скрипт $ ./myscript.sh bash: ./myscript.sh: Отказано в доступе $ chmod +x myscript.sh $ ./myscript.sh Enter a value: 10 adding value The new value is 20 Пример 4 $ cat run.sh doSam () { echo "magic" return 0 } if doSam;then echo "Its true" fi $ sh run.sh magic Its true В этом случае return 0 означает true, когда return 1 в традиционном булевом смысле означает false. Глава 4.Переменные. Переменные -это ячейка памяти,содержащаяся в себе определенные данные. Имена переменных не должны начинаться с цифры. 4.1 Присваивание значений переменным. Значения присваиваются переменным с помощью операции = Присваиваемое значение не должно отделяться пробелами от имени переменной. В одной строчке можно присвоить значение сразу нескольким переменным. $ firstname=Max lastname=Corn $ echo $firstname; echo $lastname Max Corn если значение по команде declare -i , то правая часть как вырражение $ i=3+5 ;echo $i 3+5 $ declare -i jj; jj=5+3; echo $jj 8 4.2 Подстановка переменных. Установить значение переменной,проверить. $ a=123; echo $a; 123 $ echo {$a} {123} $ echo {\$a}; {$a} echo {'$'$a} {$123} ${переменная} Использовать значение переменной для массивов. $ a=(0 1 2 ) $ echo ${a[1]} 1 ${переменная :-значение} Использовать переменную, если она указана, иначе – заданное значение. $ b=5 $ echo ${b:-10} 5 max@hp:~$ echo ${c:-10} 10 ${переменная :=значение} Использовать переменную,иначе заданное значение, присвоив его указанной переменной max@hp:~$ echo ${USER:=max2} max max@hp:~$ echo ${USER1:=max2} max2 ${переменная :?значение} Использовать указанное значение если она установлена, иначе выйти из оболочки. $ echo ${c:?125} bash: c: 125 ${переменная :+значение} Использовать указанное значение,иначе не использовать ничего. $ c=file1.txt $ echo ${c:+filen.txt} filen.txt $ echo ${d:+filen.txt} $ ${#переменная} Использовать длину указанной переменной. $ echo $c file1.txt $ echo ${#c} 9 $ ${#*},${#@} Использовать количество позиционных параметров. ${переменная #шаблон} Использовать после удаления слева теста ,совпадающего с шаблоном. Удалить самый короткий совпадающий фрагмент. c=file1.txt 1.txt ${переменная##шаблон} Удалить самый длинный совпадающий фрагмент $ echo ${c##file} 1.txt ${переменная ##шаблон} То же что и ранее ,короткий и длинный фрагмент справа. ${переменная %шаблон} ${переменная %%шаблон} $ echo ${c%.txt} file1 max@hp:~$ echo ${c%%txt} file1. ${переменная /шаблон/замена} $ data=`date` $ echo ${data} Чт июн 13 10:56:05 MSK 2019 $ echo ${data/Чт} июн 13 10:56:05 MSK 2019 ${переменная //шаблон/замена} $ echo ${data//Чт июн/Пт июль} Пт июль 13 10:56:05 MSK 2019 ${переменная /#шаблон/замена} ${переменная /%шаблон/замена} Использовать max@hp:~$ greeting="hello friend" $ declare -n message=greeting $ echo message message $ echo $message hello friend $ message="by now" $ echo $greeting by now $ {переменная@P} Вычислить значение указанной переменной. $ echo ${c@P} file1.txt $ $ {переменная@Q} Заключить в кавычки значение указанной переменной. $ c=file1.txt $ echo ${c@Q} 'file1.txt' ${!переменная } Использовать значение указанной переменной в качестве имени другой переменной ,значение которой должно быть использовано. 4.3 Косвенные переменные. Косвенные переменные-это переменные именующие другие переменные. Косвенные переменные создаются по команде declare -n Пример 1 $ greeting=privet $ echo $greeting privet $ declare -n message=greeting $ echo $message privet Пример 2 Присвоить через косвенную переменную значение основной переменной. $ message=otvet $ echo $greeting otvet Пример 3 Применение псевдонима $ text=ok $ echo $(!text) echo $(text=ok) 4.4 Переменные, встроенные в оболочку. Основные переменные. $# количество аргументов в командной строке. $-Действующие в настоящее время параметры,представленные в командной строке. $? Выходное значение последней,выполнявшейся команды. $$ Номер процесса ,присвоенный оболочке. $! Номер процесса,присвоенной команде,выполнявшейся в фоновом режиме. $0 Первое слово, имя команды. $n Oтдельные аргументы командной строки,если больше 9 форма ${n} $*,$@ Все аргументы командной строки ($1,$2..) Пример 1 $ cat >param.sh #!/bin/sh echo "$#" echo "$0" echo "$?" echo "$$" echo "$@" echo "$*" exit 0 Запускаем скрипт с параметрами a b c d