03AutomationAndScripting.md 15 KB

Automation, scripting, network tools (ssh, rsync, ftp, telnet)

Bash в базе

Несмотря на разнообразие (sh, csh, bash, zsh), все командные интерпретаторы обладают схожим набором возможностей, включающие в себя язык скриптового программирования. Рассмотрим основные возможности интерпретатора bash:

Переменные

Задаём значение:

DATESTR=`date` # угловые кавычки сохраняют стандартный вывод в переменной
UNIXTIMESTAMP=`date +%s`

Используем переменные:

echo "Дата по человечески: $DATESTR"
echo "Дата по компьютерному: $UNIXTIMESTAMP"

Условия

if

годная шпаргалка

case

Аналог switch, однако с другим синтаксисом:

#считываение ввода пользователя
echo -n 'Ваша любимый ЯП'
read lang


#осуществляем сравнения с шаблонами
case $lang in
    php)
        echo "серьезно?";;

    js|javascript)
        echo 'вранье';;

    cpp)
        echo 'вы помещением не ошиблись?';;
esac
  • Конструкция множественного выбора начинается с ключевого слова case.
  • Сразу за ключевым словом case, внутри кавычек, следует определение входящего параметра. Чаще всего это значение переменной.
  • Начало определения блока сравнений открывается ключевым словом in, расположенным за входящим параметром.
  • Каждое сравнение задается шаблоном. Он может быть строкой или числом, а также содержать механизмы подстановки. Шаблон в обязательном порядке закрывается правой круглой скобкой.
  • Сразу за правой круглой скобкой шаблона или на следующих строках после него располагаются команды, требующие выполнения при совпадении входящего параметра. Последняя команда внутри такого блока должна завершаться двумя точками с запятой «;;».
  • Если вам требуется назначить несколько шаблонов для одного и того же блока команд используйте символ «|» для их разделения. Например, «*.txt | *.bat )».
  • Блок сравнений должен завершаться ключевым словом esac.

Циклы

for


#простая последовательность чисел и текста
#всё в одну строку
for value in 'one' 'two' 3 4; do echo $value; done

#на отдельных строках
for value in 'one' 'two' 3 4
do
    echo $value
done

#перебор подготовленного массива в цикле
langs=('PHP' 'JS' 'SQL')

for lang in ${langs[@]}
do
    echo $lang
done

#использование подстановочного механизма
for letter in {a..z}
do
    echo $letter
done

#перебираем результат выполнения команды
for file in $(ls ~/)
do
    echo $file
done
  • Конструкция начинается с ключевого слова for, за которым следует блок инициализации цикла.
  • Блок инициализации открывается определением переменной, в которую будут записываться значения текущих элементов на каждом этапе выполнения.
  • После определения переменной размещается ключевое слово in. Оно является своего рода разделителем переменной и списка элементов.
  • За ключевым словом in происходит определение списка, предназначенного для перебора в цикле. Списком может быть: массив, простой ряд чисел или строк, механизмы подстановки, формирующие последовательности и т.д.
  • Блок команд, который будет выполняться для каждого элемента, задается между ключевыми словами do и done. Где do — начало, а done — конец.
  • Если ключевое слово do располагается на одной строке с определением списка, перед ним должна находиться точка с запятой.
for классический
for ((i=1; i<=15 ; i++))
do
    echo $i
done
  • Цикл со счетчиком отличается от базового только блоком инициализации.
  • Блок инициализации располагается внутри двойных круглых скобок и разделен на три выражения.
  • Каждое выражение отделяется от другого точкой с запятой «;».
  • Первое выражение вычисляется всего один раз при старте цикла. Оно задает переменную, которая будет доступна внутри блока команд.
  • Второе выражение вычисляется в начале каждого витка выполнения. Если его результатом является истина, то цикл продолжает работу.
  • Третье выражение будет вычисляться в конце каждого витка цикла и, как правило, изменяет значение переменной, заданной в начале блока инициализации.

while

#выполняем пока счетчик ниже порогового значения
counter=0

while [[ $counter -le 20 ]]
do
    echo $counter
    (( counter++ ))
done

# чтения потока ввода по строкам:
counter=0
while read line
do
    echo "$counter: $line"
    (( counter++ ))
done
  • Конструкция начинается с ключевого слова while, за которым располагается выражение, требующее проверки.
  • Блок команд, выполняемый, пока истинно выражение, задается между ключевыми словами do и done. Где do — начало, а done — конец.
  • Если ключевое слово do располагается на одной строке с выражением, перед ним должна находиться точка с запятой.

Подпрограммы

В bash нет полноценного механизма возвращения значений из функций, поэтому подпрограммы реализуют возврат результата через стандартный вывод, в месте вызова значение сохраняется с помощью угловых кавычек (backtick)

Сетевые утилиты и их возможности (ssh, rsync, ftp, telnet, netcat, sshfs)

ssh

Крайне популярная программа для сетевого доступа к терминалу, ко всему прочему позволяет передавать файлы и потоки ввода-вывода через шифрованный туннель для данных. Этот набор возможностей, в комбинации с возможностями потоков ввода-вывода утилит и ssh-ключами позволяет автоматизировать любой процесс через сеть. SSH часто используется как транспорт другими программами.

Существует ssh сервер (sshd) и ssh клиент (ssh).

SSH как обычно

Как в putty:

ssh user@host

Удаленный запуск программ

SSH позволяет не только заходить на сервер удаленно, но и запускать там команды: удаленный запуск команд на сервере используя ssh

Как видите, ssh при этом перенаправляет потоки ввода вывода с удаленной стороны на локальный компьютер и назад.

Ключи и безпарольный доступ

ssh умеет использовать криптографические ключи для аутентификации. Очень нужная штука в условиях, когда ssh используется не изредка и напрямую, а как транспорт в другой программе (sshfs, rsync, so on)

rsync

rsync означает Remote Syncronization. Утилита, которая позволяет скопировать файлы с другого компьютера по сети, при этом используя разные протоколы (ftp, ssh, ...) и экономя трафик (копируя только измененные файлы). Используется для бэкапов и, наоборот, деплоя.

ftp

FTP (File Transfer Protocol) - протокол, который изначально был задуман для закачки и скачки файлов и папок по сети. Для работы требуется ftp сервер и ftp клиент. Клиенты:

  • windows explorer
  • filezilla
  • ftp
  • lftp

telnet

Telnet - программа для удаленного доступа, которая обеспечивает передачу терминала по сети. Нешифрованная предтеча ssh. Однако, во времена, когда telnet придумали, еще не было множества клиентов для интернет-сервисов, поэтому многие сервисы имеют дружественный к telnet сетевой протокол. Например:

  • HTTP (telnet host 80)
  • SMTP (telnet host 25)
  • FTP (telnet host 21)
  • STARWARS (telnet towel.blinkenlights.nl)

И до сих пор telnet удобен для проверки работы почти или вебсервера.

netcat

Программа для перенаправление потоков ввода-вывода в TCP-соединения

# Изобразим из себя веб-браузер
echo "GET http://gitlab.a-level.com.ua/" | netcat gitlab.a-level.com.ua 80


# Изобразим из себя веб-сервер
(echo -e "HTTP/1.1 200 OK\nContent-Type: text/html\n\n Hello World";) | nc -vv -l -p 8080

# Создадим одноразовый вебсервер для отдачи файла однократно

(echo -e "HTTP/1.1 200 OK\nContent-Disposition: attachment; filename=целевое-имя-которое-увидит-клиент\nContent-Type: application/octet-stream\nConnection: close\n"; cat имя-файла-на-диске ) | nc -vv -l -p 8080

sshfs

Про sshfs говорилось, эта программа использует подсистему FUSE (filesystem in the user space) для создания виртуальной файловой системы, в которой вы можете работать с файлами через сеть используя ssh.

В целом команда работает аналогично любому монтированию:

sshfs <шо подключить> <куда подключить>

Однако скриптинг позволяет упростить и эту несложную операцию:

#!/bin/bash 
# vim: filetype=sh

SSHFS_ROOT="$HOME/sshfs" 
PERSISTENT_CHECK_TIMEOUT=5 


if [ "$1" == '' ] ; then 
    echo "Usage: $0 user@host:remotepath - Single mount"
    echo 'Sample: `sfs guest@example.com:` - mounts home directory of guest on exapmle.com into your home on localhost in folder sshfs: ~/sshfs/example.com/guest/' 
    echo "Usage: $0 user@host:remotepath -p & - Persistent mount" 
    echo 'Sample: `sfs guest@example.com: -p &` - Same as previous sample, but sfs works in background and checks for some files in local mount directory. If there no files found' 
    echo ' it tries to remount remote directory again. Useful for non-stable connections like fucking ukrtelecom or GPRS.' 
    echo ' REQUIRES SSH KEY AUTHENTICATION FOR PROMPTLESS sshfs MOUNT' 
    exit 1 
fi 

USER=`echo $1 | cut -f 1 -d '@'` 
echo "User: $USER" 
HOST=`echo $1 | cut -f 2 -d '@'` 
HOST=`echo $HOST | cut -f 1 -d ':'` 
echo "Host: $HOST" 

SSHFS_PATH="$SSHFS_ROOT/$HOST/$USER" 

mkdir -p $SSHFS_PATH > /dev/null 2>&1 
sshfs -o reconnect,ServerAliveInterval=15,ServerAliveCountMax=3 $1 $SSHFS_PATH 

if [ "$2" == '-p' ] ; then 
    echo "Persistent mode. Are you sure that you already set your public key on $1 ?" 
    while true ; do 
        sshfs $1 $SSHFS_PATH > /dev/null 2>&1 
        sleep $PERSISTENT_CHECK_TIMEOUT 
    done 
fi

Примеры

Бэкапилка на rsync + hardlinks

rsync умеет --link-dest, а именно - синхронизировать удаленное дерево, на базе предыдущего бэкапа, делая хардлинки на неизменные файлы.

Скринилка over sshfs

Что нужно для того, что бы сделать свой личный скриншот-хостинг?

Заливка дампа базы в одну строку.

если есть mysqldump, mysql и ssh, как залить дамп базы на сервер без лишнего головняка?