Базовые знания Linux админа

 

Примечание

В данной серии не будет теории и прочего

Это абсолютный базис-гайд по установке ОС и базовым навыкам в терминале

В конце будет рассмотрено несколько современных технологий в простых реализациях

После прохождения гайда у вас будет машина и несколько популярных сервисов

Все. Дальше - сами, книги, видео, стажировка

Этот гайд - выжимка на многолетние накопления вопросов на канале и сайте

Гайд будет доступен на моем сайте:

http://snakeproject.ru

Видео будут доступны на моем канале 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"

Попробуйте найти информацию в документации или интернете и применить в скриптах