Como criar (via script do instalador) uma tarefa que irá instalar o meu script bash para que ele seja executado na inicialização do DE?

3

Eu tenho lido nas últimas duas horas sobre o Upstart, .xinitrc, .xsessions, rc.local, /etc/init.d/, / etc / xdg / autostart, @reboot no crontab e tantas outras coisas que estou totalmente confuso!

Aqui está o meu script bash. Ele deve iniciar / executar após o ambiente de área de trabalho ser iniciado e deve continuar a ser executado em todos os momentos até o logout / shutdown. Deve começar novamente na reinicialização. Sempre que o DE estiver sendo executado, ele deverá ser executado.

#!/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

Eu não sei nada sobre o uso do Upstart, mas entendo que o Upstart é uma maneira de lidar com isso. Vou considerar outras abordagens mas a maioria das coisas que tenho lido sobre são muito complexas para mim. Além disso, não consigo descobrir qual abordagem atenderá aos meus requisitos (que detalharei abaixo).

Há duas etapas na minha pergunta:

  1. Como iniciar automaticamente o script acima, conforme descrito acima.

  2. Como "instalar" essa tarefa do Upstart por meio de um script bash (ou seja, meu "instalador").

Eu assumo (ou espero) que o passo 2 seja quase trivial quando eu entendi o primeiro passo.

Eu tenho que suportar todos os tipos de desktops do Ubuntu. Portanto, a chamada kdialog acima será substituída. Estou pensando em easybashgui para isso. (Ou eu poderia usar zenity no gnome DE.)

Meus requisitos são:

  1. O processo de instalação (instalação) deve ser feito através de um script bash. Eu não posso usar o método GUI descrito no AddingProgramToSessionStartup do Ubuntu, por exemplo. Eu devo ser capaz de criar scripts / automatizar o processo de instalação (instalação) usando o bash. Atualmente, é tão simples quanto ter o script bash installer copiando o script acima para /home/$USER/.kde/Autostart/

  2. O processo de instalação deve ser universal através dos derivados do Ubuntu, incluindo o Unity, o KDE e os desktops gnome. O mesmo script de instalação (instalador) deve rodar em Linux Mint, Kubuntu, Xbuntu (basicamente qualquer versão do Ubuntu e grandes derivados como o Linux Mint). Por exemplo, não podemos continuar colocando um arquivo de script em /home/$USER/.kde/Autostart/ , porque isso existe apenas no KDE.

  3. O script acima deve funcionar para cada um dos sabores limitados que usamos. Daí o nosso interesse em usar easybashgui em vez de kdialog ou zenity. Veja abaixo.

  4. O script de monitoramento instalado deve ser iniciado apenas após a área de trabalho ser iniciada, pois exibirá uma mensagem da GUI para o usuário se a atualização for encontrada.

    1. O script de monitoramento (acima) deve ser executado sem privilégios de root, é claro. Mas o instalador (script bash) pode ser executado como root.
  5. Eu não sou um desenvolvedor de verdade ou um administrador de sistemas. Esta é uma coisa voluntária em tempo parcial para mim, então precisa ser fácil / simples. Eu posso escrever scripts bash e posso programar um pouco, mas não sei nada sobre Upstart ou systemd, por exemplo. E, infelizmente, meu trabalho não me dá tempo para me tornar um especialista em sistemas init ou muito de qualquer outra coisa relacionada ao desenvolvimento e ao administrador de sistemas. Então eu tenho que ficar com soluções simples.

A versão easybashgui do script pode ser assim:

#!/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
    
por MountainX 30.06.2013 / 21:23

2 respostas

2

Iniciador

As tarefas em / etc / xdg / autostart são iniciadas pelo Desktop Environment com as credenciais do usuário atual e podem acessar a GUI, então acho que essa é a melhor escolha.

Arquivo /etc/xdg/autostart/updateNotification.desktop:

[Desktop Entry]
Name=My Update Notification
Exec=updateNotification.sh
Terminal=false
Type=Application
NoDisplay=true

Script de monitoramento

O script de monitoramento deve ser colocado em um local acessível pelo mundo. Eu recomendo / usr / local / bin porque mexer com arquivos nesse diretório não afetará o sistema operacional. Eu mudei seu roteiro um pouco.

Arquivo /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

É claro que você terá que baixar download easybashgui, extrair e instalar isso.

tar xzf easybashgui-8.0.1.tar.gz
cd easybashgui-8.0.1/
sudo make install

Instalador

Eu realmente gosto de usar arquivos bash de auto-extração porque todo o processo de instalação pode ser incorporado em um único arquivo. Tudo o que precisamos fazer é concatenar um cabeçalho bash pré-criado com um arquivo tar.

Antes de criar o arquivo, verifique se todos os arquivos estão no lugar em que deveriam estar e se têm as permissões corretas, neste caso:

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

Também podemos incluir easybashgui no instalador. Descompacte o arquivo easybashgui em / tmp:

tar zxf easybashgui-8.0.1.tar.gz -C /tmp

e tar de todos os arquivos necessários:

sudo tar zcf MyArchive.tar.gz /etc/xdg/autostart/updateNotification.desktop /usr/local/bin/updateNotification.sh /tmp/easybashgui-8.0.1/

Crie o cabeçalho bash que irá descompactar o arquivo e instalar o easybashgui. Arquivo 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__

Por fim, junte o cabeçalho e o arquivo:

cat header.sfx MyArchive.tar.gz > MyInstaller.sh

Agora você pode copiar o instalador para outra máquina, dar permissão de execução e executar sudo ./MyInstaller.sh .

É isso. Espero que ajude.

    
por Eric Carvalho 02.07.2013 / 01:42
0

Parece que estou me deparando com uma questão menor com a excelente resposta fornecida por Eric Carvalho.

Eu criei um arquivo .tar.bz e testei que posso extraí-lo corretamente com:

tar xzf MyArchive.tar.bz -C /home/$USERN/Downloads/

Eu criei o bash 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__

Eu criei o arquivo / instalador do shell auto-extraível:

cat header.sfx MyArchive.tar.bz > MyInstaller.sh

Eu defino as permissões (a + x). Os resultados da execução do instalador são:

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�.��'

Parece que o arquivo MyArchive.tar.bz é extraído corretamente, a partir de uma olhada dentro da pasta extraída.

Esse tipo de erro toca bem?

Meu primeiro palpite foi que exit 0 está sendo ignorado, mas não sei por que isso aconteceria ... Percebi que exit 0 está na linha 125 e o erro é relatado como estando na linha 132, que seria parte do arquivo de arquivo concatenado.

A próxima coisa que tentei consiste nas seguintes alterações no headers.sfx:

primeira linha:

#!/bin/bash -xv

últimas linhas:

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__

Desta vez, o resultado parece:

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��

A saída real inclui muito mais " ", mas o acima captura apenas a parte legível.

Notas da solução:

O primeiro erro que cometi foi que pensei que não deveria haver um caractere de nova linha no final da última linha do arquivo header.sfx. Veja abaixo:

# The following line must be the last one. Don't place any character (including newline characters) after it.
__BEGIN_DATA__

Acontece que deve haver uma nova linha no final da linha __BEGIN_DATA__

O segundo problema que encontrei é que a ativação da depuração bash (por exemplo, set -x ) impede o funcionamento da sequência awk / tail / tar dos comandos.

Essas duas mudanças funcionaram para mim em um caso de teste. (E foi realmente apenas uma mudança: corrigir o meu mal-entendido sobre os caracteres finais da nova linha).

No entanto, no meu exemplo da vida real, encontrei problemas adicionais. Acontece que as permissões de arquivos nos arquivos dentro do arquivo são importantes. Havia um arquivo dentro do meu arquivo que tinha permissões muito restritas e esse arquivo fazia com que todo o script bash de extração automática falhasse na fase de extração. No entanto, as extrações manuais no gerenciador de arquivos da GUI ou as extrações da linha de comando usando o tar foram bem-sucedidas. Portanto, os scripts bash de auto-extração são um pouco mais sensíveis a coisas como permissões de arquivo dentro do arquivo (e eu não estou falando sobre permissões no próprio arquivo).

Além disso, qualquer "lixo à direita" fará com que o script bash de extração automática falhe. Exemplo:

gzip: stdin: decompression OK, trailing garbage ignored

Eu recebi esta mensagem de um arquivo e o script bash de extração automática não executou nenhum comando após a extração (mesmo que a extração pareça estar bem, como a mensagem sugere). É possível que algo como 2> /dev/null resolvesse este último problema ...

    
por MountainX 03.07.2013 / 00:17