Содержание

Файлы внутри скриптов или deploy на bash'е

Отсюда: http://blog.eqlbin.ru/2010/12/deploy-bash.html


Одним из интересных свойств bash-скриптов является то, что в них можно запихивать файлы, которые затем сам скрипт будет из себя извлекать при запуске. Таким образом, например, устроены скрипты установки JRE и JDK для Linux. Используя это свойство, можно довольно легко создавать скрипты для автоматизированного развертывания каких-либо систем, библиотек и т.п.. Приведу примеры извлечения текстовых и бинарных данных из bash-скриптов.

Скрипты внутри скриптов

Используя команду cat, из выполняющегося скрипта можно вытащить любые данные, которые находятся между вызовом cat и какой-либо текстовой меткой. Это удобно использовать в первую очередь для извлечения текстовых данных, например скриптов. Т.е. можно создавать bash-скрипты, которые при выполнении сами будут создавать различные скрипты, причем используя переменные можно добиться хорошей гибкости.

Простой пример скрипта создающего другие скрипты:

	
#!/bin/bash
 
# Каталог для развертывания
DEPLOY_PATH="./scripts/inner-scripts"
# Имя первого вложенного скрипта
FIRST_SCRIPT_NAME="script-inner-1.sh"
# Имя второго вложенного скрипта
SECOND_SCRIPT_NAME="script-inner-2.sh"
 
echo "Развертывание вложенных скриптов"
 
# Создание каталога для развертывания если его нет
if [ ! -d $DEPLOY_PATH ]
then
    echo "Создание каталога $DEPLOY_PATH"
    mkdir -p $DEPLOY_PATH
fi
 
cd $DEPLOY_PATH
 
echo "Создание скрипта $FIRST_SCRIPT_NAME"
 
# Извлечение текста между вызовом cat и первой меткой _EOF_
cat  > ./$FIRST_SCRIPT_NAME << _EOF_
#!/bin/bash
# первый вложенный скрипт
echo "Первый скрипт запущен!"
echo "Запуск второго скрипта..."
./$SECOND_SCRIPT_NAME
_EOF_
 
echo "Создание скрипта $SECOND_SCRIPT_NAME"
 
# Извлечение текста между вызовом cat и второй меткой _EOF_
cat > ./$SECOND_SCRIPT_NAME << _EOF_
#!/bin/bash
# второй вложенный скрипт
echo "Второй скрипт запущен!"
_EOF_
 
# Установка прав на выполнение скриптов
chmod 755 $FIRST_SCRIPT_NAME $SECOND_SCRIPT_NAME
 
echo "Развертывание скриптов закончено!"

Приведенный код создаст два скрипта, причем первый скрипт будет запускать второй скрипт при выполнении.

Бинарные файлы внутри скриптов

Помимо текстовых данных из скрипта можно извлекать предварительно записанные в них бинарные файлы, например архивы. Особенность при создании такого скрипта в том, что сначала надо написать сам скрипт, а потом с помощью команды cat загнать в него необходимый файл. \\Пример скрипта, который извлекает из себя архив с jar-файлами, распаковывает его и удаляет архив:

	
#!/bin/bash
 
DEPLOY_PATH="./libs/jar/odfdom-simple"
ARCH_NAME="odfdom-libs.tar.gz"
 
echo "Развертывание библиотек ODFDOM"
 
# Создание каталога если его нет
if [ ! -d $DEPLOY_PATH ]
then
    echo "Создание каталога $DEPLOY_PATH"
    mkdir -p $DEPLOY_PATH
fi
 
echo "Создание скрипта $FIRST_SCRIPT_NAME"
# Вытаскиваем архив из скрипта (начиная с 30-й строки до конца скрипта)
tail -n +30 "$0" > $DEPLOY_PATH/$ARCH_NAME
 
cd $DEPLOY_PATH
 
# Распаковка архива
tar xzf $ARCH_NAME
 
# Удаление архива
rm -f $ARCH_NAME
 
# Выход из программы с кодом 0
exit 0
##################################################################
# 30-я строка; здесь начнутся бинарные данные; эту строку включать в скрипт не надо

После того, как будет написана последовательность команд скрипта, необходимо в конце вставить пустую строку, сохранить скрипт и выполнить в терминале нечто вроде:

cat my_arch.tar.gz >> my_script.sh

После выполнения этой команды архив my_arch.tar.gz станет частью скрипта my_script.sh. Для извлечения архива в приведенном примере используется команда tail -n +30 «$0» > $DEPLOY_PATH/$ARCH_NAME, которая в данном случае извлекает бинарные данные и перенаправляет вывод в файл ./libs/jar/odfdom-simple/odfdom-libs.tar.gz. Параметр -n +30 означает, что выводить данные надо начиная с 30 строки файла, а под «$0» скрывается имя выполняющегося скрипта.

После того как данные извлечены, можно распаковывать архив, распихивать файлы по каталогам, создавать симлинки и в общем делать всё, что нужно для развертывания вашей системы. Самое главное не забудьте вызвать команду exit до того, как начнутся бинарные данные, иначе bash попытается выполнить и их :)