web-dev-qa-db-fra.com

Comment créer (via un script d'installation) une tâche qui installera mon script bash afin qu'il s'exécute au démarrage de DE?

Je lis depuis deux heures environ Upstart, .xinitrc, .xsessions, rc.local, /etc/init.d/,/etc/xdg/autostart, @reboot in crontab et tant d'autres choses que je ' m totalement confus!

Voici mon script bash. Il devrait démarrer/s'exécuter après le démarrage de l'environnement de bureau et continuer à fonctionner à tout moment jusqu'à la déconnexion/l'arrêt. Il devrait recommencer au redémarrage. Chaque fois que le DE est en cours d'exécution, il devrait être exécuté.

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

Je ne connais pas l'utilisation d'Upstart, mais je comprends que cette méthode est un moyen de gérer cela. Je considérerai autres approches mais la plupart des choses que j'ai lues sont trop complexes pour moi. De plus, je ne sais pas quelle approche répondra à mes exigences (que je détaillerai ci-dessous).

Ma question comporte deux étapes:

  1. Comment démarrer automatiquement le script ci-dessus, comme décrit ci-dessus.

  2. Comment "installer" cette tâche Upstart via un script bash ("mon installateur").

Je suppose (ou espère) que l'étape 2 est presque triviale une fois que j'ai compris l'étape 1.

Je dois prendre en charge tous les types de bureaux Ubuntu. Par conséquent, l’appel kdialog ci-dessus sera remplacé. J'envisage easybashgui pour cela. (Ou je pourrais utiliser zenity sur les gnomes DE.)

Mes exigences sont:

  1. Le processus d'installation (installation) doit être effectué via un script bash. Je ne peux pas utiliser la méthode graphique décrite dans la documentation Ubuntu AddingProgramToSessionStartup , par exemple. Je dois être capable de script/automatiser le processus d'installation (installation) en utilisant bash. Actuellement, il est aussi simple que de laisser le script d’installation bash copier le script ci-dessus dans /home/$USER/.kde/Autostart/

  2. Le processus de configuration doit être universel pour tous les dérivés Ubuntu, y compris Unity, KDE et les bureaux gnome. Le même script d'installation (programme d'installation) doit s'exécuter sur Linux Mint, Kubuntu, Xbuntu (essentiellement n'importe quelle version d'Ubuntu et de ses principaux dérivés, tels que Linux Mint). Par exemple, nous ne pouvons pas continuer à mettre un fichier de script dans /home/$USER/.kde/Autostart/ parce qu'il n'existe que sous KDE.

  3. Le script ci-dessus devrait fonctionner pour chacune des variantes limitées que nous utilisons. D'où notre intérêt à utiliser easybashgui à la place de kdialog ou de zenity. Voir ci-dessous.

  4. Le script de surveillance installé ne doit être démarré qu'après le bureau est démarré puisqu'il affichera un message d'interface graphique à l'utilisateur si la mise à jour est trouvée.

    1. Le script de surveillance (ci-dessus) devrait bien sûr être exécuté sans privilèges root. Mais l'installateur (script bash) peut être exécuté en tant que root.
  5. Je ne suis pas un vrai développeur ou un administrateur système. C'est une activité de bénévolat à temps partiel pour moi, il faut donc que ce soit facile/simple. Je peux écrire des scripts bash et programmer un peu, mais je ne connais rien à Upstart ou à systemd, par exemple. Et, malheureusement, mon travail ne me laisse pas le temps de devenir un expert des systèmes init ou de presque toute autre activité liée au développement et à l’administrateur système. Je dois donc rester avec des solutions simples.

La version easybashgui ​​du script pourrait ressembler à ceci:

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

Lanceur

Les tâches de/etc/xdg/autostart sont démarrées par l'environnement de bureau avec les informations d'identification de l'utilisateur actuel. Ils peuvent accéder à l'interface graphique. Je pense donc que c'est le meilleur choix.

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

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

Script de surveillance

Le script de surveillance doit être placé dans un emplacement accessible au monde. Je recommande/usr/local/bin parce que manipuler les fichiers de ce répertoire n’affectera pas le système d’exploitation. J'ai changé votre script un peu.

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

Bien sûr, vous devrez télécharger easybashgui, l'extraire et l'installer.

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

Installateur

J'aime beaucoup utiliser les fichiers auto-extractibles bash car tout le processus d'installation peut être intégré dans un seul fichier. Tout ce que nous avons à faire est de concaténer un en-tête bash pré-construit avec un fichier tar.

Avant de créer l’archive, assurez-vous que tous les fichiers sont à la place qui leur convient et qu’ils ont les droits appropriés, dans ce cas:

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

Nous pouvons également inclure easybashgui ​​dans le programme d'installation. Décompressez l’archive easybashgui ​​dans/tmp:

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

et tar tous les fichiers requis:

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

Créez l'en-tête bash qui décompressera l'archive et installera easybashgui. Fichier 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__

Enfin, rejoignez l’en-tête et l’archive:

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

Vous pouvez maintenant copier ce programme d'installation sur un autre ordinateur, lui donner l'autorisation d'exécution et exécuter Sudo ./MyInstaller.sh.


C'est ça. J'espère que ça aide.

2
Eric Carvalho

Je semble rencontrer un problème mineur avec l'excellente réponse fournie par Eric Carvalho.

J'ai créé un fichier .tar.bz et testé que je peux l'extraire correctement avec:

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

J'ai créé le 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__

J'ai créé le fichier/installateur auto-extractible:

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

Je fixe les permissions (a + x). Les résultats de l'exécution du programme d'installation sont les suivants:

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

Il semble que le fichier MyArchive.tar.bz soit correctement extrait, en regardant dans le dossier extrait.

Est-ce que ce type d'erreur vous dit quelque chose?

Ma première hypothèse était que exit 0 était ignoré, mais je ne savais pas trop pourquoi. Ce fut le cas… J'ai remarqué que exit 0 est à la ligne 125 et que l'erreur est signalée à la ligne 132. , qui ferait partie du fichier d’archive concaténé.

La prochaine chose que j'ai essayée consiste à apporter les modifications suivantes à headers.sfx:

première ligne:

#!/bin/bash -xv

dernières lignes:

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__

Cette fois le résultat ressemble à:

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

La sortie réelle inclut beaucoup plus de "" mais ce qui précède en capture la seule partie lisible.

Notes de solution:

La première erreur que j'ai commise est que je pensais qu'il ne devait pas y avoir de caractère de nouvelle ligne à la fin de la dernière ligne du fichier header.sfx. Voir ci-dessous:

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

Il s'avère qu'il devrait y avoir une nouvelle ligne à la fin de la ligne __BEGIN_DATA__

Le deuxième problème que j'ai trouvé est que l'activation du débogage bash (par exemple, set -x) empêche la séquence de commandes awk/tail/tar de fonctionner.

Ces deux modifications ont fonctionné pour moi sur un cas de test. (Et ce n'était vraiment qu'un changement: corriger mon malentendu à propos des caractères de nouvelle ligne finaux.)

Cependant, dans mon cas réel, j'ai rencontré des problèmes supplémentaires. Il s'avère que les autorisations de fichier sur les fichiers à l'intérieur l'archive importent réellement. Il y avait un fichier dans mes archives qui avait des autorisations très restreintes et ce fichier a entraîné l'échec de l'intégralité du script bash à extraction automatique lors de la phase d'extraction. Toutefois, des extractions manuelles dans le gestionnaire de fichiers GUI ou des extractions en ligne de commande à l'aide de tar ont abouti. Les scripts bash auto-extractibles sont donc un peu plus sensibles à des éléments tels que les autorisations de fichiers à l'intérieur de l'archive (et je ne parle pas d'autorisations sur l'archive elle-même).

De plus, toute "traînée de fond" entraînera l'échec du script bash à extraction automatique. Exemple:

gzip: stdin: decompression OK, trailing garbage ignored

J'ai reçu ce message d'une archive et le script bash auto-extractible n'a pas réussi à exécuter les commandes après l'extraction (même si l'extraction semble avoir été correcte, comme le message l'indique). Il est possible que quelque chose comme 2> /dev/null résolve ce dernier problème ...

0
MountainX