Последние пару часов я читал об Upstart, .xinitrc, .xsessions, rc.local, /etc/init.d/, / etc / xdg / autostart, @reboot в crontab и многих других вещах. что я полностью сбит с толку!
Вот мой сценарий bash. Он должен запускаться / запускаться после запуска среды рабочего стола, и он должен продолжать работать все время до выхода из системы / завершения работы. Это должно начаться снова при перезагрузке. Каждый раз, когда DE работает, он должен работать.
#!/bin/bash
while true; do
if [[ -s ~/.updateNotification.txt ]]; then
read MSG < ~/.updateNotification.txt
kdialog --title 'The software has been updated' --msgbox "$MSG"
cat /dev/null > ~/.updateNotification.txt
fi
sleep 3600
done
exit 0
Я знаю ноль об использовании Upstart, но я понимаю, что Upstart - один из способов справиться с этим. Я рассмотрю другие подходы , но большинство вещей, о которых я читал, слишком сложны для меня. Кроме того, я не могу понять, какой подход будет отвечать моим требованиям (о чем я расскажу ниже).
В моем вопросе есть два шага:
Как автоматически запустить сценарий выше, как описано выше.
Как «установить» задачу Upstart с помощью bash-скрипта (т.е. мой «установщик»).
Я предполагаю (или надеюсь), что шаг 2 почти тривиален, когда я понимаю шаг 1.
Я должен поддерживать все версии рабочих столов Ubuntu. Таким образом, вызов kdialog выше будет заменен. Я рассматриваю easybashgui для этого. (Или я мог бы использовать zenity в DE гномов.)
Мои требования:
Процесс установки (установки) должен выполняться через скрипт bash. Я не могу использовать метод GUI, описанный в Ubuntu doc AddingProgramToSessionStartup , например. Я должен быть в состоянии сценарий / автоматизировать процесс установки (установки) с помощью Bash. В настоящее время это так же просто, как сценарий bash installer скопировать вышеуказанный сценарий в /home/$USER/.kde/Autostart/
Процесс установки должен быть универсальным для всех производных Ubuntu, включая Unity, KDE и рабочие столы gnome. Тот же сценарий установки (установщик) должен работать в Linux Mint, Kubuntu, Xbuntu (в основном любой вариант Ubuntu и основных производных, таких как Linux Mint). Например, мы не можем продолжать помещать файл скрипта в /home/$USER/.kde/Autostart/
, потому что он существует только в KDE.
Приведенный выше скрипт должен работать для каждого из ограниченных вариантов, которые мы используем. Отсюда наш интерес к использованию easybashgui вместо kdialog или zenity. Смотри ниже.
Установленный сценарий мониторинга должен запускаться только после рабочего стола, поскольку он будет отображать сообщение GUI пользователю, если будет найдено обновление.
Я не настоящий разработчик или системный администратор. Для меня это работа на добровольной основе, поэтому она должна быть легкой / простой. Я могу писать сценарии bash и немного программировать, но я ничего не знаю, например, об Upstart или systemd. И, к сожалению, моя работа не дает мне времени стать экспертом по системам инициализации или многим другим вопросам, связанным с разработкой и сисадмином. Поэтому я должен придерживаться простых решений.
Версия скрипта easybashgui может выглядеть так:
#!/bin/bash
source easybashgui
while true; do
if [[ -s ~/.updateNotification.txt ]]; then
read MSG < ~/.updateNotification.txt
message "$MSG"
cat /dev/null > ~/.updateNotification.txt
fi
sleep 3600
done
exit 0
Средство запуска
Задачи в/etc/xdg/autostart запускаются Настольной средой с учетными данными текущего пользователя, и они могут получить доступ к GUI, таким образом, я думаю, что это - лучший выбор.
Файл/etc/xdg/autostart/updateNotification.desktop:
[Desktop Entry]
Name=My Update Notification
Exec=updateNotification.sh
Terminal=false
Type=Application
NoDisplay=true
Контроль сценария
Контролирующий сценарий должен быть помещен в мировое доступное местоположение. Я рекомендую/usr/local/bin, потому что питание с файлами в том каталоге не будет влиять на ОС. Я изменил Вас сценарий немного.
Файл/usr/local/bin/updateNotification.sh:
#!/bin/bash
# Exit if this script is already running.
[[ $(pgrep -c -u $USER -f "^/bin/bash ${0}$") -gt 1 ]] && exit 0
NotifFile=~/.updateNotification.txt
source easybashgui
# Wait some time before starting monitoring the file, so the user doesn't get a popup right after logging in.
sleep 120
while true; do
if [[ -s $NotifFile ]]; then
read MSG < $NotifFile
# Only empty the file if the message is successfully displayed.
message "$MSG" && echo -n > $NotifFile
fi
sleep 3600
done
exit 0
Конечно, необходимо будет загрузить easybashgui, извлечь его и установить его.
tar xzf easybashgui-8.0.1.tar.gz
cd easybashgui-8.0.1/
sudo make install
Установщик
Мне действительно нравится использовать самораспаковывающиеся файлы удара, потому что процесс полной установки может быть встроен в единственный файл. Все, что мы должны сделать, связывают предварительно созданный заголовок удара с файлом tar.
Прежде, чем создать архив удостоверяются, что все файлы находятся в месте, они должны быть и иметь правильные полномочия в этом случае:
sudo chown root:root /etc/xdg/autostart/updateNotification.desktop
sudo chown root:root /usr/local/bin/updateNotification.sh
sudo chmod 644 /etc/xdg/autostart/updateNotification.desktop
sudo chmod 755 /usr/local/bin/updateNotification.sh
Мы можем также включать easybashgui в установщик. Распакуйте архив easybashgui к/tmp:
tar zxf easybashgui-8.0.1.tar.gz -C /tmp
и tar
все необходимые файлы:
sudo tar zcf MyArchive.tar.gz /etc/xdg/autostart/updateNotification.desktop /usr/local/bin/updateNotification.sh /tmp/easybashgui-8.0.1/
Создайте заголовок удара, который распакует архив и установит easybashgui. Файл header.sfx:
#!/bin/bash
DATA=`awk '/^__BEGIN_DATA__/ { print NR + 1; exit 0; }' $0`
tail -n+$DATA $0 | tar zx -C /
# Additional installation steps
cd /tmp/easybashgui-8.0.1/
make install
exit 0
# The following line must be the last one. Don't place any character after it.
__BEGIN_DATA__
Наконец, присоединитесь к заголовку и архиву:
cat header.sfx MyArchive.tar.gz > MyInstaller.sh
Теперь можно скопировать тот установщик в другую машину, дать ему разрешение выполнения и работать sudo ./MyInstaller.sh
.
Именно. Надежда это помогает.
Я, кажется, сталкиваюсь с незначительной проблемой с превосходным ответом, предоставленным Eric Carvalho.
Я создал .tar.bz файл и протестировал это, я могу правильно извлечь его с:
tar xzf MyArchive.tar.bz -C /home/$USERN/Downloads/
Я создал удар header.sfx:
#!/bin/bash
USERN=`whoami`
if [ $(id -u) = "0" ] ; then
USERN=$SUDO_USER
fi
DATA=`awk '/^__BEGIN_DATA__/ { print NR + 1; exit 0; }' $0`
tail -n+$DATA $0 | tar xz -C /home/$USERN/Downloads/
if [ $? -ne 0 ] ; then
exit 1
echo
# Additional installation steps follow
#bash commands here
#the last command calls my main installer script:
bash ./another_bash_script.sh
exit 0 #this is line 125
# The following line must be the last one. Don't place any character (including newline characters) after it.
__BEGIN_DATA__
Я создал самораспаковывающийся файл/установщик оболочки:
cat header.sfx MyArchive.tar.bz > MyInstaller.sh
Я установил полномочия (a+x). Результаты запуска установщика:
tester@mint15_VirtualBox ~/Downloads $ sudo ./MyInstaller.sh
./ExampleInstaller.2013.07.01.sh: line 132: syntax error near unexpected token `('
./ExampleInstaller.2013.07.01.sh: line 132: `.����D������V G��c�� ��������Ӭ��ӡ|@��|M�.�/�~��w�O��*��B���l�}Ω�O�.��'
Кажется, что файл MyArchive.tar.bz извлечен правильно от взгляда вокруг внутренней части извлеченная папка.
Тот тип ошибки звонит в звонок?
Мое первое предположение было этим exit 0
игнорируется, но я не уверен, почему это имело бы место... Я заметил это exit 0
находится на строке 125, и об ошибке сообщают как являющийся на строке 132, который был бы частью связанного архивного файла.
Следующая вещь, которую я попробовал, состоит из следующих изменений в headers.sfx:
первая строка:
#!/bin/bash -xv
последние строки:
exit 0
echo "we should never reach here!"
# The following line must be the last one. Don't place any character (including newline characters) after it.
__BEGIN_DATA__
На этот раз результат похож:
tester@mint15_VirtualBox ~/Downloads $ sudo ./MyInstaller.sh
#!/bin/bash -xv
USERN=`whoami`
whoami
++whoami
[snip]
exit 0
echo "we should never reach here!"
# The following line must be the last one. Don't place any character (including newline characters) after it.
__BEGIN_DATA__
�#�Q��P\߷&�и����Ƶ��4 и��
��������Ӭ��ӡ|@��|M�.�/���B���l�}Ω�O�.
./ExampleInstaller.sh: line 134: syntax error near unexpected token `('
./ExampleInstaller.sh: line 134: `.����D���c��
Эффективная выходная мощность включает намного больше "���", но вышеупомянутые получения единственная читаемая часть его.
Первая ошибка, которую я сделал, состоит в том, что я думал, там, как предполагалось, не был символом новой строки в конце последней строки в header.sfx файле. Посмотрите ниже:
# The following line must be the last one. Don't place any character (including newline characters) after it.
__BEGIN_DATA__
Оказывается, что должна быть новая строка в конце строки __BEGIN_DATA__
Вторая проблема, которую я нашел, состоит в том что, включая удар, отлаживающий (например, set -x
) препятствует тому, чтобы awk/tail/tar последовательность команд работала.
Эти два изменения получили его работающий на меня на тестовом сценарии. (И это было действительно всего одно изменение: исправление моего недоразумения о заключительных символах новой строки.)
Однако на моем реальном примере я столкнулся с дополнительными проблемами. Оказывается, что полномочия файла на файлах в архиве действительно имеют значение. Был один файл в моем архиве, который очень ограничил полномочия, и этот файл заставил целый самораспаковывающийся сценарий удара перестать работать в фазе извлечения. Однако ручные извлечения в файловом менеджере GUI или извлечения командной строки с помощью tar оба, за которыми следуют. Так самораспаковывающиеся сценарии удара немного более чувствительны к вещам как полномочия файла в архиве (и я не говорю о полномочиях на самом архиве).
Кроме того, любой "запаздывающий мусор" заставит самораспаковывающийся сценарий удара перестать работать. Пример:
gzip: stdin: decompression OK, trailing garbage ignored
У меня было это сообщение из одного архива, и самораспаковывающемуся сценарию удара не удалось выполнить любые команды после извлечения (даже при том, что извлечение, кажется, было прекрасно, как сообщение предполагает). Возможно что что-то как 2> /dev/null
решил бы эту последнюю проблему...