Базовые знания Linux админа
Примечание
В данной серии не будет теории и прочего
Это абсолютный базис-гайд по установке ОС и базовым навыкам в терминале
В конце будет рассмотрено несколько современных технологий в простых реализациях
После прохождения гайда у вас будет машина и несколько популярных сервисов
Все. Дальше - сами, книги, видео, стажировка
Этот гайд - выжимка на многолетние накопления вопросов на канале и сайте
Гайд будет доступен на моем сайте:
Видео будут доступны на моем канале YouTube:
https://www.youtube.com/channel/UCR6j95DKI80MFXIw2iJ3f1w
План:
4 часть — bash скрипты, автоматизация задач
Символы подстановки в bash
Шаблоны перечисления - {X1..X2} (пример создаст файлы с окончанием в промежутке 1-4):
peasant@server:~$ touch file{1..4}
В подстановочных символах "?" - один любой знак (пример выведет все файлы из 5 символов):
peasant@server:~$ echo ?????
file1 file2 file3 file4
Пример выведет все файлы из 5 символов, начинающиеся на file, с любым символом на конце:
peasant@server:~$ echo file?
file1 file2 file3 file4
Подстановочный символ "*" - любое количество любых знаков:
peasant@server:~$ echo f*
file1 file2 file3 file4
Подстановочный диапазон [X1-X2], ищет совпадения с диапазоном:
peasant@server:~$ echo file[1-2]
file1 file2
Подстановочный диапазон исключения [^X1-X2], ищет НЕсовпадения с диапазоном:
peasant@server:~$ echo file[^1-2]
file3 file4
Скрипты bash
Скрипты в баш начинаются с указания интерпретатора:
#!/usr/bin/bash
Узнать, где находится bash можно командой:
which bash
/usr/bin/bash
Сделать скрипт исполняемым можно добавив права:
chmod +x test.sh
Комментарии в bash скриптах начинаются с символа - #
Пример написания простейшего скрипта(войдите текстовым редактором vi test.sh):
#!/usr/bin/bash
#This is first script
echo "This is echo line"
Сделайте скрипт исполняемым файлом:
chmod +x test.sh
Запуск скрипта:
./test.sh
This is echo line
Вариант запуска с отладкой:
bash -x ./test.sh
+ echo 'This is echo line'
This is echo line
Пользуйтесь для дебага опцией -x
В больших и незнакомых скриптах она бесценна
Простые функции и передача аргументов
В данном скрипте мы сделаем пару функций:
#!/usr/bin/bash
# Не принимает аргументов
function echo_text()
{
echo "This is echo line"
}
# Принимает аргументы, выводит их
function echo_text_args()
{
echo "This is echo line args: $1 $2"
}
# Вызов функций
echo_text
echo_text_args "1_arg" "2_arg"
echo_text_args $1 $2
Вызов скрипта с передачей аргументов (1_global_arg и 2_global_arg) и без:
./test.sh
This is echo line
This is echo line args: 1_arg 2_arg
This is echo line args:
./test.sh 1_global_arg 2_global_arg
This is echo line
This is echo line args: 1_arg 2_arg
This is echo line args: 1_global_arg 2_global_arg
Как видно, имена аргументов в скрипте одинаковы, результат - разный
Глобально и локально в функции это разные переменные
Переменные в bash
Назначить значение переменной с помощью оператора - "="
Символы ";" означает сделать следующую команду после предыдущей
Удобно, чтоб не писать много строк
var1=variable_1_value ; var2=$var1
echo $var1 $var2
variable_1_value variable_1_value
Пример с числовыми переменными (выведется echo как строка):
var1="1" ; var2=2 ; var3=$var1+$var2
echo $var3
1+2
Пример с числовыми переменными (выведется echo как строка):
var1=1 ; var2=2 ; var3=$var1+$var2
echo $var3
1+2
Примеры с числовыми переменными (выведутся echo как число):
var1="1" ; var2=2 ; var3=$(($var1+$var2))
echo $var3
3
echo $(($var1+$var2))
3
var1=1 ; var2=2 ; var3=$(($var1+$var2))
echo $var3
3
Переменные в скриптах
$@ - список переданных аргументов
$# - количество переданных аргументов
$0 - имя скрипта
$цифра - номер переданного скрипту аргумента
Пример скрипта:
#!/usr/bin/bash
echo $@ ; echo $# ; echo $0 ; echo $1 ; echo $2 ; echo $3
Пример вызова скрипта:
./test.sh arg1 arg2
arg1 arg2
2
./test.sh
arg1
arg2
Логическая конструкция if (проверка "если выполняется условие")
Логические операторы проверки:
строка пуста | -z |
строка не пуста | -n |
строки равны | =, (==) |
строки неравны | != |
равно | -eq |
неравно | -ne |
меньше | -lt,(< ) |
меньше или равно | -le,(<=) |
больше | -gt,(>) |
больше или равно | -ge,(>=) |
отрицание логического выражения | ! |
логическое "И" | -a,(&&) |
логическое "ИЛИ" | -o,(||) |
Конструкция if - elif - else (если истина - то - иначе):
#!/usr/bin/bash
a=6
if [ $a -eq 5 ]
then
echo "a is 5"
elif [ $a -eq 6 ]
then
echo "a is 6"
else
echo "a is not 5 and 6"
fi
Вызов скрипта:
./test.sh
a is 6
Где в скрипте:
if, then, fi - обязательные конструкции
elif и else - необязательные конструкции
Введем проверку на количество принимаемых аргументов:
#!/usr/bin/bash
if [[ $# -ne 1 ]]
then
echo 'Wrong number of arguments! Enter one'
exit 2
fi
if [ $1 -eq 5 ]
then
echo "arg is 5"
elif [ $1 -eq 6 ]
then
echo "arg is 6"
else
echo "arg is not 5 and 6"
fi
Проверяем:
./test.sh
Wrong number of arguments! Enter one
./test.sh 1 2
Wrong number of arguments! Enter one
./test.sh 1
arg is not 5 and 6
./test.sh 5
arg is 5
Для самостоятельной работы найдите информацию по конструкции "case" (аналог конструкции if) и попробуйте ее в написании скриптов
Цикл for
По сути цикл - переборщик значений
Пример перебора числовых значений:
#!/usr/bin/bash
for a in 1 2 3 4 5 6 7 8 9; do
echo $a "detected!!!"
done
Вызов:
./test.sh
1 detected!!!
2 detected!!!
3 detected!!!
4 detected!!!
5 detected!!!
6 detected!!!
7 detected!!!
8 detected!!!
9 detected!!!
Пример перебора текстовых значений:
#!/usr/bin/bash
var='arg1 arg2 arg3'
for a in $var; do
echo $a "detected!!!"
done
Вызов:
./test.sh
arg1 detected!!!
arg2 detected!!!
arg3 detected!!!
Пример перебора с условием, делай, пока верно (i меньше или равно 3), добавляй единицу (i++):
#!/usr/bin/bash
for ((i=1;i<=3;i++))
do
echo $i
done
Вызов:
./test.sh
1
2
3
Пример опроса локальной сети (192.168.0.1 - 192.168.0.5) по icmp:
#!/usr/bin/bash
for ((i=1;i<=5;i++))
do
echo -n "ping 192.168.0.$i "
if ping -W 1 -c 1 192.168.0.$i > /dev/null
then
echo "Ping success"
else
echo "Ping failed"
fi
done
Пример вызова:
./test.sh
ping 192.168.0.1 Ping success
ping 192.168.0.2 Ping failed
ping 192.168.0.3 Ping failed
ping 192.168.0.4 Ping failed
ping 192.168.0.5 Ping failed
Выполнение утилиты в ОС из скрипта
#!/usr/bin/bash
my_current_dir=$(pwd)
echo $my_current_dir
Проверка:
./test.sh
/home/peasant
Цикл while
Цикл while можно описать как "выполняй, пока условие истинно":
#!/usr/bin/bash
a=0;
while [ "$a" -le 5 ]; do
echo "value of a: $a"
a=$(expr $a + 1)
done
Вызов:
./test.sh
value of a: 0
value of a: 1
value of a: 2
value of a: 3
value of a: 4
value of a: 5
Стандартные ввод, вывод, ошибки в Linux
Обозначаются как:
0 — STDIN(ввод), 1 — STDOUT(вывод) и 2 — STDERR(ошибка)
Осуществляется операторами: <, >, <<, >>
1> - перенаправление стандартного вывода
2> - перенаправление вывода ошибок
Примеры
Отправить вывод команды в файл (затрет все в файле):
echo 'test' > file.txt
Отправить вывод команды в файл (добавит информацию в файл):
echo 'test_2' >> file.txt
Отправить вывод команды в "никуда" (например для гашения вывода в логи):
echo 'test' > /dev/null
Отправлять стандартный вывод в /dev/null, а ошибки(STDERR) в стандартный вывод(&1):
echo 'test' > /dev/null 2>&1
Отправлять стандартный вывод и ошибки в /dev/null:
echo 'test' &> /dev/null
Скрипт при запуске выдает первую строку с echo и текст ошибки деления второй строки:
#!/usr/bin/bash
var1=1
var2=0
echo $var1 " / " $var2
echo $((var1/var2))
Вывод скрипта:
./test.sh
1 / 0
./test.sh: line 5: var1/var2: division by 0 (error token is "var2")
Перенаправим стандартный вывод в "никуда":
./test.sh 1> /dev/null
./test.sh: line 5: var1/var2: division by 0 (error token is "var2")
Перенаправим поток ошибок в "никуда":
./test.sh 2> /dev/null
1 / 0
Конструкция 2>&1
Поток с номером 2 (stderr) перенаправить в поток с номером 1 (stdout)
Т.е. сообщения об ошибках направляем через поток, через который печатается обычный вывод
Неоднозначный пример, имеем несколько файлов:
ls file?
file1 file2 file3 file4
ls fly?
ls: cannot access 'fly?': No such file or directory
Вывод в случаях с "file" логично будет пуст
Первая команда ( ls file? >/dev/null 2>&1 )
>/dev/null - направляем поток 1(stdout) в /dev/null, все сообщения, попадающие в поток 1(stdout), будут направлены в /dev/null
Вторая команда ( ls file? 2>&1 >/dev/null )
2>&1 - перенаправляем поток 2(stderr) в поток 1(stdout), т.к. поток 1 уже ассоциирован с /dev/null, все сообщения попадут в /dev/null
Вывод в случаях с "fly":
Разберитесь самостоятельно, почему во второй команде вывод попал на экран
Для самостоятельной работы изучите тему "Массивы в bash"
Попробуйте найти информацию в документации или интернете и применить в скриптах