Si vous avez besoin de programmer une tâche Linux qui ne doit s’exécuter qu’une seule fois, cron est une solution trop lourde. Les commandes de la suite « at » sont parfaitement adaptées à cette situation ! De plus, si vous préférez que les processus ne se lancent que lorsque le système dispose de ressources disponibles, vous pouvez opter pour le traitement par lots.
Comment organiser vos tâches sous Linux
Le service cron gère une liste de tâches qui sont exécutées à des moments précis. Ces opérations et programmes s’activent en arrière-plan selon les planifications établies. Cela offre une grande souplesse pour automatiser des actions répétitives. Que vous souhaitiez exécuter une action toutes les heures, à une heure précise chaque jour, ou encore une fois par mois ou par an, cron est capable de gérer cela.
Cependant, cette méthode n’est pas idéale si vous souhaitez programmer une tâche unique. Bien sûr, vous pourriez l’ajouter à cron, mais il vous faudrait ensuite revenir pour supprimer l’entrée correspondante dans crontab après son exécution, ce qui n’est pas très pratique.
Dans le monde Linux, il y a de fortes chances que si vous rencontrez un problème, quelqu’un d’autre l’ait déjà rencontré avant vous. Heureusement, étant donné l’ancienneté des systèmes d’exploitation de type Unix, il est probable qu’une solution ait déjà été mise en place pour votre situation.
Pour le cas mentionné précédemment, cette solution existe et se nomme « at ».
Installation de la commande « at »
Nous avons dû installer cette commande sous Ubuntu 18.04 et Manjaro 18.1.0 (elle était déjà préinstallée sous Fedora 31).
Pour l’installer sur Ubuntu, utilisez la commande suivante :
sudo apt-get install at
Une fois l’installation terminée, vous pouvez démarrer le service « at » avec cette instruction :
sudo systemctl enable --now atd.service

Sous Manjaro, l’installation de « at » se fait avec cette commande :
sudo pacman -Sy at

Après l’installation, utilisez cette commande pour activer le service « at » :
sudo systemctl enable --now atd.service

Quel que soit votre distribution, vous pouvez vérifier si le service « atd » est en cours d’exécution en tapant la commande suivante :
ps -e | grep atd

Comment utiliser la commande « at » de façon interactive
Pour utiliser « at », vous devez lui spécifier une date et une heure d’exécution. Il existe une grande souplesse quant à la manière de les indiquer, et nous explorerons cela plus loin.
Cependant, même si l’utilisation d’at est interactive, vous devez toujours fournir la date et l’heure à l’avance. Si vous n’indiquez rien sur la ligne de commande, ou si vous entrez des informations qui ne sont pas une date et une heure, « at » répondra par « Heure brouillée », comme ci-dessous :
at
at banana

Les dates et les heures peuvent être explicites ou relatives. Par exemple, si vous voulez qu’une commande soit exécutée dans une minute, « at » sait ce que signifie « maintenant ». Vous pouvez donc utiliser « now » et ajouter une minute, comme ceci :
at now + 1 minute

at affiche un message et une invite « at », puis attend que vous entriez les commandes que vous souhaitez planifier. Tout d’abord, examinons le message, comme ci-dessous :

Ce message indique qu’une instance du shell « sh » est lancée et va exécuter les commandes à l’intérieur. Vos commandes ne seront pas exécutées dans le shell Bash, qui est compatible avec « sh », mais possède un ensemble de fonctionnalités plus étendu.
Si vos commandes ou vos scripts tentent d’utiliser une fonction ou une installation fournie par Bash, mais pas par « sh », ils échoueront.
Il est facile de tester si vos commandes ou vos scripts s’exécuteront correctement dans « sh ». Pour cela, utilisez la commande « sh » pour démarrer un shell « sh » :
sh

L’invite de commande se transforme en signe dollar ($), et vous pouvez maintenant exécuter vos commandes et vérifier qu’elles fonctionnent comme prévu.
Pour revenir au shell Bash, tapez la commande « exit » :
exit
Vous ne verrez aucun affichage standard ni message d’erreur des commandes. En effet, le shell « sh » se lance en arrière-plan et s’exécute sans interface visuelle.
Toute sortie des commandes, qu’elle soit positive ou négative, vous est envoyée par e-mail. Cet e-mail est envoyé via le système de messagerie interne à la personne qui a exécuté la commande « at ». Cela signifie que vous devez installer et configurer ce système de messagerie interne.
De nombreux systèmes Linux (la plupart) n’ont pas de système de messagerie interne, car cela est rarement nécessaire. Ceux qui en ont utilisent généralement un outil comme sendmail ou postfix. Si votre système n’a pas de système de messagerie interne, vous pouvez configurer vos scripts pour qu’ils écrivent dans des fichiers, ou rediriger la sortie vers des fichiers pour avoir un journal des opérations.
Si la commande ne génère aucun affichage standard ou message d’erreur, vous ne recevrez pas d’e-mail. Beaucoup de commandes Linux indiquent leur succès par un silence, donc dans la plupart des cas, vous ne recevrez aucun e-mail.
Il est maintenant temps de taper une commande pour « at ». Pour cet exemple, nous utiliserons un petit script appelé « sweep.sh » qui supprime les fichiers avec les extensions « *.bak », « *.tmp » et « *.o ». Indiquez le chemin d’accès à la commande comme montré ci-dessous, puis appuyez sur Entrée.

Une autre invite de commande apparaît, et vous pouvez ajouter autant de commandes que vous le souhaitez. Cependant, il est généralement plus pratique de regrouper vos commandes dans un script unique, puis d’appeler ce script depuis « at ».
Appuyez sur Ctrl + D pour indiquer que vous avez terminé d’ajouter des commandes. « at » affiche un signal

Une fois la tâche exécutée, tapez la commande suivante pour consulter votre messagerie interne :

S’il n’y a pas de message, vous pouvez supposer que la commande a réussi. Bien sûr, dans ce cas, vous pouvez vérifier si les fichiers « *.bak », « *.tmp » et « *.o » ont bien été supprimés pour vous en assurer.
Tapez ce qui suit pour exécuter à nouveau l’ensemble du processus :
at now + 1 minute

Après une minute, tapez la commande suivante pour vérifier à nouveau vos e-mails :

Voilà, nous avons reçu un message ! Pour lire le premier message, tapez « 1 », puis appuyez sur Entrée.

Nous avons reçu un e-mail de la part de « at » car les commandes du script ont généré des messages d’erreur. Dans cet exemple, il n’y avait aucun fichier à supprimer, car lors de la première exécution du script, tous les fichiers avaient déjà été supprimés.
Appuyez sur « D + Entrée » pour supprimer l’e-mail, puis sur « Q + Entrée » pour quitter le programme de messagerie.
Formats de date et d’heure
La commande « at » accepte une grande variété de formats de date et d’heure. Voici quelques exemples :
Exécuter à 11h00 :
at 11:00 AM
Exécuter à 11h00 demain :
at 11:00 AM tomorrow
Exécuter à 11h00 le même jour de la semaine prochaine :
at 11:00 AM next week
Exécuter à cette heure, le même jour de la semaine prochaine :
at next week
Exécuter à 11h00 vendredi prochain :
at 11:00 AM next fri
Exécuter à cette heure vendredi prochain :
at next fri
Exécuter à 11h00 à cette date, le mois prochain :
at 11:00 AM next month
Exécuter à 11h00 à une date précise :
at 11:00 AM 3/15/2020
Exécuter dans 30 minutes :
at now + 30 minutes
Exécuter dans deux heures :
at now + 2 hours
Exécuter à cette heure demain :
at tomorrow
Exécuter à cette heure jeudi :
at thursday
Exécuter à 12h00 :
at midnight
Exécuter à 12h00 :
at noon
Si vous êtes britannique, vous pouvez même programmer une commande pour qu’elle s’exécute à l’heure du thé (16h) :
at teatime
Afficher la file d’attente des tâches
Vous pouvez utiliser la commande « atq » pour visualiser la file d’attente des tâches planifiées, comme illustré ci-dessous.

Pour chaque commande dans la file d’attente, « atq » affiche les informations suivantes :
L’identifiant de la tâche.
La date prévue.
L’heure prévue.
La file d’attente dans laquelle la tâche se trouve. Les files d’attente sont identifiées par « a », « b », etc. Les tâches normales planifiées vont dans la file d’attente « a », tandis que les tâches planifiées avec « batch » (expliquées plus loin) vont dans la file d’attente « b ».
La personne qui a planifié la tâche.
Utiliser « at » en ligne de commande
Vous n’êtes pas obligé d’utiliser « at » de manière interactive. Il est également possible de l’utiliser directement en ligne de commande, ce qui facilite l’utilisation dans des scripts.
Vous pouvez rediriger des commandes vers « at », comme ceci :
echo "sh ~/sweep.sh" | at 08:45 AM

La tâche est acceptée et planifiée par « at », et le numéro de la tâche ainsi que sa date d’exécution sont affichés comme précédemment.
Utilisation de « at » avec des fichiers de commandes
Vous pouvez également stocker une série de commandes dans un fichier, puis le transmettre à « at ». Ce fichier peut être un simple fichier texte. Il n’est pas nécessaire que ce soit un script exécutable.
Pour transmettre un nom de fichier à « at », vous pouvez utiliser l’option « -f » (fichier) de la manière suivante :
at now + 5 minutes -f clean.txt

Vous pouvez obtenir le même résultat en redirigeant le fichier vers « at » :
at now + 5 minutes < clean.txt

Supprimer des tâches planifiées de la file d’attente
Pour supprimer une tâche planifiée de la file d’attente, vous pouvez utiliser la commande « atrm ». Pour afficher la file d’attente et connaître le numéro de la tâche à supprimer, vous pouvez utiliser « atq ». Ensuite, utilisez ce numéro de tâche avec « atrm », comme montré ci-dessous :
atq
atrm 11
atq

Comment obtenir un affichage détaillé des tâches
Comme nous l’avons mentionné précédemment, vous pouvez programmer des tâches bien à l’avance. Il est possible que vous oubliiez ce qu’une tâche en particulier va effectuer. La commande « atq » affiche les tâches présentes dans la file d’attente, mais ne donne pas d’informations sur leurs actions. Si vous souhaitez obtenir une vue détaillée d’une tâche, vous pouvez utiliser l’option « -c » (cat).
Pour commencer, nous allons utiliser « atq » pour connaître le numéro de la tâche :
atq

Maintenant, nous allons utiliser la tâche numéro 13 avec l’option « -c » :
at -c 13

Voici une explication des informations obtenues sur la tâche :
Première ligne : elle indique que les commandes seront exécutées dans le shell « sh ».
Deuxième ligne : elle indique que les commandes seront exécutées avec un identifiant d’utilisateur et un identifiant de groupe égal à 1000. Ce sont les valeurs de la personne qui a exécuté la commande « at ».
Troisième ligne : la personne qui reçoit les e-mails envoyés.
Quatrième ligne : le masque d’utilisateur est 22. C’est le masque utilisé pour définir les autorisations par défaut pour tous les fichiers créés dans cette session du shell. Le masque est soustrait de 666, ce qui nous donne 644 (l’équivalent octal de « rw-r–r–« ).
Données restantes : la majorité sont des variables d’environnement.

Résultats d’un test : un test vérifie que le répertoire d’exécution est accessible. Si ce n’est pas le cas, une erreur est générée et l’exécution de la tâche est abandonnée.
Les commandes à exécuter. Elles sont listées et le contenu des scripts planifiés s’affiche. Notez que, bien que notre exemple de script ci-dessus soit écrit pour s’exécuter dans Bash, il sera toujours exécuté dans le shell « sh ».
La commande « batch »
La commande « batch » fonctionne de la même manière que la commande « at », mais avec trois différences importantes :
Vous ne pouvez utiliser la commande « batch » que de manière interactive.
Au lieu de planifier l’exécution des tâches à une heure précise, vous les ajoutez à une file d’attente. « batch » les exécute lorsque la charge moyenne du système est inférieure à 1,5.
En raison de ce qui précède, vous ne spécifiez jamais de date ou d’heure avec la commande « batch ».
Pour utiliser « batch », entrez simplement son nom sans paramètres :
batch

Ensuite, ajoutez les tâches de la même manière que vous le feriez avec la commande « at ».
Gérer les accès à la commande « at »
Les fichiers « at.allow » et « at.deny » permettent de contrôler qui peut utiliser les commandes de la suite « at ». Ces fichiers se trouvent dans le répertoire « /etc ». Par défaut, seul le fichier « at.deny » existe et il est créé lors de l’installation de « at ».
Voici comment cela fonctionne :
« at.deny » : liste les applications et les entités qui ne peuvent pas utiliser « at » pour planifier des tâches.
« at.allow » : liste les utilisateurs qui peuvent utiliser « at » pour planifier des tâches. Si le fichier « at.allow » n’existe pas, « at » n’utilise que le fichier « at.deny ».
Par défaut, tout le monde peut utiliser « at ». Si vous voulez limiter les utilisateurs autorisés, utilisez le fichier « at.allow » pour lister ceux qui peuvent l’utiliser. C’est plus simple que d’ajouter tous ceux qui ne peuvent pas utiliser « at » dans le fichier « at.deny ».
Voici à quoi ressemble le fichier « at.deny » :
sudo less /etc/at.deny

Le fichier liste les composants du système d’exploitation qui ne peuvent pas être utilisés par « at ». Beaucoup d’entre eux sont exclus pour des raisons de sécurité, et il est important de ne pas les supprimer du fichier.

Maintenant, nous allons éditer le fichier « at.allow ». Nous allons y ajouter « Dave » et « Mary », et personne d’autre ne sera autorisé à utiliser « at ».
Tout d’abord, tapez la commande suivante :
sudo gedit /etc/at.allow

Dans l’éditeur, ajoutez les deux noms comme montré ci-dessous, puis enregistrez le fichier.

Si une autre personne tente d’utiliser « at », elle sera informée qu’elle n’y est pas autorisée. Par exemple, imaginons qu’un utilisateur nommé « eric » entre la commande suivante :
at
Il se verra refuser l’accès, comme montré ci-dessous.

Encore une fois, Eric n’est pas présent dans le fichier « at.deny ». Dès que vous ajoutez quelqu’un dans le fichier « at.allow », tous les autres se voient refuser l’autorisation d’utiliser « at ».
Idéal pour les tâches ponctuelles
Comme vous pouvez le constater, les commandes « at » et « batch » sont parfaitement adaptées aux tâches qui ne doivent être exécutées qu’une seule fois. Pour résumer :
Si vous avez besoin de faire quelque chose qui n’est pas un processus régulier, planifiez-le avec « at ».
Si vous souhaitez qu’une tâche ne s’exécute que lorsque la charge du système est suffisamment faible, utilisez « batch ».