Comment passer des heures à Bash (et garder le time imparti même si la session était fermée)?

J'ai créé le script suivant pour installer puis désinstaller PHPmyadmin sur Ubuntu 16.04 …

Mon but est d'utiliser ce script chaque fois que je veux utiliser PHPmyadmin, puis, après un certain time comme 2 heures , le supprimer. Cette méthode d' installation-utilisation-désinstallation est utilisée pour des raisons de security (en gardant MySQL inaccessible comme possible et accessible localement pour de très courtes périodes).

bash /dev/fd/15 15<< 'EOF0' #!/bin/bash -x # Install commands: sudo apt-get install phpmyadmin sudo phpenmod mcrypt sudo phpenmod mbssortingng cat << EOF1 >> /etc/apache2/apache2.conf Include /etc/phpmyadmin/apache.conf EOF1 sudo service apache2 restart # Unnstall commands: sleep 2h sudo phpdismod mcrypt mbssortingng sudo apt-get purge phpmyadmin sudo service apache2 restart sed -i 's/Include \/etc\/phpmyadmin\/apache.conf/ /g /etc/apache2/apache2.conf EOF0 

Comme je l'ai noté dans les commentaires de Jeff (et comme j'ai édité l'exemple de code), je pourrais utiliser la command sleep , mais sleep , sous sa forme classique, exige que la session rest ouverte et la window ferme parfois quelque soit la raison. une réponse canonique est nécessaire qui montre comment donner cette suspension de 2 heures mais de telle manière que même si je ferme la window par erreur ou intentionnellement ou que mon PC redémarre d'une quelconque raison ou qu'il y a une coupure de courant — La suspension et tout commands après qu'il continuera à fonctionner sur le VPS, sans aucune interférence de ma part.

Alors, comment pourrais-je exécuter les commands de désinstallation 2 heures après les commands d'installation, mais d'une manière indépendante de la session?

Vous pouvez l'atteindre avec l'utilitaire at .

Pour une seule command, faites:

 at 'now + 2 hours' -f /path/to/uninstall.sh 

Pour plusieurs commands, servez votre script au shell via cat heredocument:

 cat << EOF | at 'now + 2 hours' command1 command2 ........ EOF 

Alternativement, vous pourriez réaliser cela avec une solution systemd (encore une fois, si vous l'avez installé)

 systemd-run --on-active=2h -- /bin/bash /path/to/uninstall.sh 

Comme je peux le voir, vous avez access à sudo et vous pouvez démarrer des services. Vous pouvez donc utiliser le service atd et at command pour planifier votre tâche:

 echo 'touch $HOME/`date -j +%s`.txt' | at + 2 minutes 

Et pour plus d'une command, vous avez deux options:

  1. Combiner echo commands echo :

     (echo "command1" echo "command2" echo "command3" ) | at + 2 hours 
  2. Utilisez le file temporaire pour la list des commands:

      tmp_file=$(mktemp --tmpdir uninstall_commands.XXXX) echo "command1" >> ${tmp_file} echo "command2" >> ${tmp_file} echo "command3" >> ${tmp_file} at -f ${tmp_file} + 2 hours rm -f -- ${tmp_file} 

En supposant deux scripts ( faire une chose, le faire bien ):

install.sh

 #!/bin/sh -eu sudo apt-get install phpmyadmin sudo phpenmod mcrypt mbssortingng printf 'Include /etc/phpmyadmin/apache.conf' >> /etc/apache2/apache2.conf sudo service apache2 restart 

uninstall.sh

 #!/bin/sh -eu sudo phpdismod mcrypt mbssortingng sudo apt-get purge phpmyadmin sudo service apache2 restart sed -i 's/Include \/etc\/phpmyadmin\/apache.conf/ /g /etc/apache2/apache2.conf 

La réponse la plus simple à laquelle je peux penser est exactement ce que vous voulez est

 ./install.sh && sleep 2h && ./uninstall.sh >>/var/log/mylog.log 2>&1 

où chaque script inclut en plus une command ssh pour se connecter à votre server. Cette approche résiste au cycle d'alimentation du server, mais pas à votre terminal.

En alternative, je simplifierais cette réponse principalement à cause du comportement bizarre d'où atd met sa sortie et utilise plutôt

 nohup sleep 2h && ./uninstall.sh >>/var/log/mylog.log 2>&1 & 

Une fois exécuté, vous avez maintenant environ 2 heures pour faire ce que vous voulez faire, et une fois le time écoulé, le process de désinstallation se produira. Cette approche ne résiste pas au cycle d'alimentation du server.

Cette réponse évite les dependencies et active le diagnostic / le debugging en capturant et en enregistrant de manière pertinente les résultats pertinents.

Tout d'abord, vous devez structurer votre code en deux scripts, ou au less en deux fonctions distinctes dans le même script: le premier pour l'installation, le second pour la purge. Ainsi, vous pouvez exécuter soit script / fonction si nécessaire. Les deux scripts / fonctions doivent également être idempotents, c'est-à-dire qu'ils doivent ignorer l'installation / la purge au cas où cela serait déjà fait.

Ensuite, vous pouvez simplement créer un cronjob pour appeler le script de purge toutes les 2 heures, ou créer un cronjob plus périodique qui appelle le script de purge if-and-only-si l'installation date d'au less 2h. Cela résisterait à un redémarrage du server, de sorte que le package sera toujours purgé.

Je ne sais pas si cette solution pourrait répondre à vos besoins, mais vous pouvez essayer.

Si vous oubliez un instant l'arrêt / redémarrage du PC, alors cela fonctionne dans bash sans terminal de piégeage (vous pouvez l'essayer comme une command de ligne pour le test):

 sleep 10 && yad --text="10 seconds passed" && exit & 

La command ci-dessus, bien que je ne l'attendais pas, fonctionne même si je ferme ma window de terminal.

PS: Si vous le combinez avec nohup, la command sera exécutée même si vous vous déconnectez.

Comme solution de contournement, vous pouvez split votre script initiall dans deux scripts plus petits; un script pour l'installation d'un script pour la suppression, quelque chose comme ceci:

 #script_to_install.sh sudo apt-get install phpmyadmin sudo phpenmod mcrypt mbssortingng printf 'Include /etc/phpmyadmin/apache.conf' >> /etc/apache2/apache2.conf sudo service apache2 restart sleep 7200 && path/to/script_to_remove.sh & exit #exit the first script to free terminal (or even close the terminal) #end of script_to_install.sh #script_to_remove.sh #Optionally you can use xterm -e (or similar) to bring up a terminal window automatically to see the output of the commands sudo phpdismod mcrypt mbssortingng sudo apt-get purge phpmyadmin sudo service apache2 restart sed -i 's/Include \/etc\/phpmyadmin\/apache.conf/ /g /etc/apache2/apache2.conf exit #end of script_to_remove.sh 

Pour revenir à la partie de redémarrage du PC, je pense que cela peut être résolu en écrivant l'heure de début dans un file journal temp, et une fois que vous redémarrez, vous pouvez surveiller ce file temp (c.-à-d. testé).

Dans bash, ajoutez votre script avec l'instruction sleep dans votre file ~/.bash_logout . En csh, ce serait .logout.

J'ai aussi aimé la suggestion de quelqu'un d'utiliser à. Vous pouvez également envisager d'écrire un script qui agit comme une fonction de type «police» via cron.

J'ai trouvé ceci sur ce site qui peut être utile: Comment exécuter un script pendant que Gnome se déconnecte

À mon humble avis, cette approche d'installation et de purge temporaire de phpmyadmin est un hack hideux. Vous pourriez simplement ssh -L3307:localhost:3306 , c.-à-d. Que vous ssh -L3307:localhost:3306 un auditeur sur un port local ( -L3307 ) qui se connecte et se connecte à un port distant ( localhost:3306 ). Ensuite, si vous voulez parler à la database MySQL distante, utilisez simplement localhost:3307 sur la machine locale. Vous n'avez pas besoin d'installer quoi que ce soit à distance, le tunnel mourrait immédiatement lors de la déconnection, et vous pouvez utiliser n'importe quel outil MySQL localement (par exemple MySQL Workbench ou SQirreL).

Il y a de meilleures façons.

  1. Installez phpMyAdmin sur un hôte virtuel dédié avec un port que vous connaissez seulement (par exemple 56887 ).

  2. Setup knockd pour ouvrir ce port sur votre request, pour votre IP seulement.

     [phpMyAdmin] sequence = 2000,3000,4000 seq_timeout = 15 start_command = /usr/sbin/iptables -A INPUT -s %IP% -p tcp --dport 56887 -j ACCEPT cmd_timeout = 7200 stop_command = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 56887 -j ACCEPT 
  3. Utilisez handy knock pour ouvrir le port:

     knock myserver.example.com 2000 3000 4000 

C'est tout! Aucune réinstallation nécessaire. Aucun file déplacé.

La security habituelle par le biais d'obscurités s'applique. Un phpMyAdmin mal configuré peut ne pas être suffisamment protégé par un tel piratage. Vous devez le configurer correctement, peu importe quoi. Mais si vous le faites, ces hacks deviennent inutiles.

J'ai pu combiner timeout ( sleep ), heredoc externe, heredoc interne, nohup , traitement de fond et tty-stdout dans le script suivant.

C'est bien si vous avez besoin d'un moyen rapide pour installer quelque chose, puis l'effacer automatiquement après un certain time:

 bash /dev/fd/5 5<< 'EOF0' #!/bin/bash -x apt-get install SOME_UTILITY1 -y cat << EOF1 > ~/utility.sh sleep 1h apt-get purge SOME_UTILITY1 -y EOF1 chmod 755 ~/utility.sh & nohup ~/utility.sh & EOF0 

Appuyez sur Retour (Entrée) lorsque vous obtenez le message suivant, pour continuer à fonctionner normalement dans Bash (le message apparaîtra au moment où le script atteint nohup :

nohup: ajout de la sortie à '/USER_LOCATION/nohup.out'