Предварительная настройка операционной системы
Первым делом нужно установить несколько важных пакетов:
|
1 |
apt-get install wget rpm-build rpmdevtools gcc make |
С помощью одной лишь этой команды мы загружаем в систему утилиту для скачивания файлов по сети, софт для сборки установочного пакета, компилятор СИ, утилиту для сборки исходников, а также программу для создания рабочей среды в виде каталогов. Всё это нам потребуется дальше.
Все указанные в команде пакеты нужны для нашего варианта RPM сборки. В вашем случае могут потребоваться и другие зависимости, просто пропишите их через пробел. Если нужных пакетов в системе не окажется, вы получите сообщение об ошибке при первой же попытке выполнить сборку.
Последний шаг предварительной настройки операционной системы – создание отдельного пользователя. Делать это от имени пользователя с правами доступа уровня root не стоит, так как любая ошибка при указании путей может привести к тому, что какие-то файлы или даже целые директории будут потеряны. Итак, выполните команду:
|
1 |
useradd creator -m |
Таким образом мы создали пользователя creator и отдельный домашний каталог для него. Чтобы все дальнейшие действия будем совершать от его имени, пропишите:
|
1 |
su - creator |
Настройка окружения пользователя
Убедитесь, что находитесь в нужном каталоге. В качестве этого каталога может выступать абсолютно любая папка, созданная для этой цели. В рассматриваемом примере используем домашнюю директорию пользователя creator, которую создали ранее.
Чтобы удостовериться, что находитесь в нужной директории, пропишите команду:
|
1 |
$ pwd |
Если консоль выдаст вам сообщение «/home/creator», вы в правильном месте. Если видите что-то другое, просто перейдите в домашний каталог с помощью команды:
|
1 |
$ cd ~ |
И затем создайте структуру каталогов для сборки:
|
1 |
$ rpmdev-setuptree |
Теперь в нашем домашнем каталоге пользователя creator появится папка rpmbuild, содержащая такую структуру:
- BUILD — здесь расположены файлы, появляющиеся в процессе создания RPM-пакета.
- RPMS — здесь будут лежать готовые пакеты.
- SOURCES — содержит исходники для сборки RPM-пакетов.
- SPECS — здесь содержатся файлы с описанием сборки.
- SRPMS — содержит исходники RPM-файлов.
Теперь мы с вами готовы к загрузке исходника и его подготовке к дальнейшим процессам.
test
2.2. Создание двоичного файла из .sh
Shell Script Compiler, или SHC, — это инструмент, который кодирует или шифрует скрипты. Таким образом он предотвращает нежелательные изменения и скрывает исходный код. В нашем примере мы будем использовать универсальный компилятор оболочки. Существует множество других инструментов для компиляции или обфускации скриптов.
Прежде всего давайте создадим скрипт sum.sh, который будет возвращать сумму введенных чисел:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<span class="hljs-meta">#!/bin/bash</span> total=0 <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-variable">$@</span>; <span class="hljs-keyword">do</span> <span class="hljs-keyword">if</span> [ ! -z “<span class="hljs-variable">${i##[0-9]*}</span>” ]; <span class="hljs-keyword">then</span> <span class="hljs-built_in">echo</span> “Please enter numeric only” <span class="hljs-built_in">exit</span> 1 <span class="hljs-keyword">fi</span> total=$((<span class="hljs-variable">$total</span> + <span class="hljs-variable">$i</span>)) <span class="hljs-keyword">done</span> <span class="hljs-keyword">if</span> [ <span class="hljs-variable">$total</span> -eq 0 ]; <span class="hljs-keyword">then</span> <span class="hljs-built_in">echo</span> “Plesae execute script like: <span class="hljs-variable">$0</span> 10 20 30” <span class="hljs-built_in">exit</span> 0 <span class="hljs-keyword">fi</span> <span class="hljs-built_in">echo</span> <span class="hljs-variable">$total</span></code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
Прежде чем запускать его, нам нужно изменить права доступа, чтобы его можно было запустить:
|
1 2 3 |
$ <span class="hljs-built_in">chmod</span> +x sum.sh $ ./sum.sh 8 9 10 27</code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
Далее давайте загрузим и установим последнюю версию SHC. Затем скомпилируем скрипт и преобразуем его в двоичный файл:
|
1 |
$ shc -U -f sum.sh</code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
Будут созданы два новых файла: sum.sh.x.c, версия скрипта на языке C, и sum.sh.x, двоичная версия. Теперь мы можем запустить sum.sh.x как двоичный файл:
|
1 2 |
$ <span class="hljs-built_in">mv</span> sum.sh.x sum.bin $ ./sum.bin</code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
3. Самораспаковывающийся установщик
Обычно для установки, обновления и удаления пакетов мы используем менеджер пакетов. Они автоматизируют процесс загрузки, извлечения и проверки пакетов.
Однако это не единственный способ управления установкой. Добавление двоичной полезной нагрузки или архивного файла в сценарий оболочки — один из способов распространения пакета. Самораспаковывающийся установщик извлекает эту полезную нагрузку и копирует содержимое в соответствующее место.
В этой статье мы рассмотрим, как использовать файлы .sh в качестве установщика. Для примера создадим исходный пакет:
|
1 |
$ <span class="hljs-built_in">mkdir</span> demo-package && <span class="hljs-built_in">touch</span> demo-package/demo-app.txt</code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
Затем соберите и заархивируйте демонстрационный пакет:
|
1 |
$ tar -cvf archive.tar demo-package ; gzip -9 archive.tar</code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
Теперь давайте создадим сценарий установки installer.sh:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span class="hljs-meta">#!/bin/bash</span> <span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">die</span></span>() { <span class="hljs-built_in">echo</span> <span class="hljs-string">"Error!"</span>; <span class="hljs-built_in">exit</span> 1; } installer=<span class="hljs-string">"<span class="hljs-subst">$(pwd)</span>/<span class="hljs-subst">$(basename $BASH_SOURCE)</span>"</span> <span class="hljs-built_in">cd</span> ~/ || die <span class="hljs-built_in">echo</span> <span class="hljs-string">"Installing demo-app to ~/demo-app..."</span> archive=$(grep -a -n <span class="hljs-string">"__ARCHIVE_BELOW__:$"</span> <span class="hljs-variable">$installer</span> | <span class="hljs-built_in">cut</span> -f1 -d:) <span class="hljs-built_in">echo</span> $(<span class="hljs-built_in">tail</span> -n +$((archive + <span class="hljs-number">1</span>)) <span class="hljs-variable">$installer</span>) <span class="hljs-built_in">tail</span> -n +$((archive + <span class="hljs-number">1</span>)) <span class="hljs-variable">$installer</span> | gzip -vdc - | tar -xvf - > /dev/null || die <span class="hljs-comment"># run some post installation if any</span> <span class="hljs-comment"># ./app_name/bin/post_install_configuration.sh || die</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"Installation complete!"</span> <span class="hljs-built_in">exit</span> 0 __ARCHIVE_BELOW__:</code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
Затем добавьте архив в installer.sh:
|
1 |
$ <span class="hljs-built_in">cat</span> archive.tar.gz >> installer.sh</code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
Теперь сделайте его исполняемым:
|
1 |
$ <span class="hljs-built_in">chmod</span> +x installer.sh</code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
И наконец, наш установщик готов. Мы можем запустить его, чтобы установить наш пакет в ~/:
|
1 |
$ ./installer.sh</code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
Не рекомендуется использовать этот пример в рабочей среде из-за его уязвимости для вредоносных модификаций. Кроме того, поскольку они не работают с менеджером пакетов, могут возникнуть проблемы с разрешением зависимостей. Поэтому в некоторых таких пакетах используются статически связанные исполняемые файлы, то есть в них добавлены все необходимые библиотеки. Эти дополнительные библиотеки занимают немного больше памяти при использовании по сравнению с установкой через менеджер пакетов.
3.1. Использование makeself
Мы также можем использовать инструмент командной строки, такой как makeself, для создания самораспаковывающегося установщика. В нем есть множество опций, необходимых для установки. Он включает контрольную сумму для обеспечения целостности и самоконтроля, которые устраняют основной недостаток безопасности в нашем предыдущем примере.
Синтаксис:
|
1 |
$ makeself.sh [args] package_directory file_name label startup_script [script_args]</code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
В этом примере у нас есть исходный пакет /demo-app, и мы собираемся создать установщик под названием demo-pkg.run:
|
1 2 3 4 5 6 7 8 9 10 |
$ makeself.sh --notemp ./demo-app ./demo-pkg.run <span class="hljs-string">"SFX archive for backup"</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">"Extraction done"</span> Header is 715 lines long About to compress 4 KB of data... Adding files to archive named <span class="hljs-string">"./demo-pkg.run"</span>... ./demo.txt CRC: 3275129549 MD5: a718fbcfbb01730655ecaf5695dcb95b Self-extractable archive <span class="hljs-string">"./demo-pkg.run"</span> successfully created.</code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
|
1 2 3 4 5 6 |
$ ./demo-pkg.run Creating directory demo-app Verifying archive integrity... 100% MD5 checksums are OK. All good. Uncompressing SFX archive <span class="hljs-keyword">for</span> backup 100% Extraction <span class="hljs-keyword">done</span> </code><button class="hljs-copy-button" data-copied="false">Копировать</button> |
Мы можем заменить echo «Извлечение выполнено» нашим сценарием запуска. Этот сценарий запуска может делать всё, что может делать любой сценарий оболочки с файлами пакета на диске; он может переместить пакет в соответствующую директорию.