52 votes

Comment exécuter des commandes dans une file d'attente

J'ai besoin de copier plusieurs fichiers dans plusieurs dossiers. Je peux ajouter toutes mes commandes de copie à un script bash script et l'exécuter, mais je dois alors attendre qu'il se termine si je veux ajouter d'autres commandes à cette "file d'attente" de copie.

Existe-t-il un moyen d'exécuter des commandes en tant que file d'attente et d'ajouter d'autres commandes à cette file d'attente en cours d'exécution ?

Expliqué différemment, je veux lancer une tâche de longue haleine. Pendant qu'elle s'exécute, je veux en lancer une autre qui ne démarre pas tant que la première n'est pas terminée. Puis ajouter une autre tâche après la dernière et ainsi de suite. Est-ce possible d'une manière ou d'une autre ?

31voto

rob Points 3107

Ajouter & à la fin de votre commande pour l'envoyer en arrière-plan, et ensuite wait avant de passer au suivant. Par exemple :

$ command1 &
$ wait; command2 &
$ wait; command3 &
$ ...

28voto

En at qui est surtout connu pour exécuter des commandes à un moment précis, dispose également d'une fonction de file d'attente et on peut lui demander de commencer à exécuter des commandes maintenant. Il lit la commande à exécuter à partir de l'entrée standard.

echo 'command1 --option arg1 arg2' | at -q myqueue now
echo 'command2 ...' | at -q myqueue now

En batch La commande est équivalente à at -q b -m now ( -m ce qui signifie que la sortie de la commande, s'il y en a une, vous sera envoyée par courrier, comme le fait cron). Toutes les variantes d'Unix ne supportent pas les noms de file d'attente ( -q myqueue ) ; vous pouvez être limité à une seule file d'attente appelée b . Le système at est limité aux noms de file d'attente à une lettre.

13voto

greenwar Points 513

Les solutions de Brad et de Mankoff sont toutes deux de bonnes suggestions. Une autre solution, similaire à une combinaison des deux, consisterait à utiliser Écran GNU pour mettre en œuvre votre file d'attente. Cela a l'avantage de pouvoir fonctionner en arrière-plan, vous pouvez vérifier à tout moment, et la mise en file d'attente de nouvelles commandes les colle simplement dans le tampon pour qu'elles soient exécutées après la sortie des commandes précédentes.

D'abord, courir :

$ screen -d -m -S queue

(c'est d'ailleurs le bon moment pour jouer avec des . fichiers screenrc )

Cela créera une session d'écran en arrière-plan pour votre file d'attente.

Maintenant, mettez en file d'attente autant de commandes que vous le souhaitez :

screen -S queue -X stuff "echo first; sleep 4; echo second^M"

Je fais plusieurs commandes dans ce qui précède juste pour tester. Votre cas d'utilisation ressemblerait probablement plus à

screen -S queue -X stuff "echo first^M"
screen -S queue -X stuff "echo second^M"

Notez que le "^M" dans ma ligne ci-dessus est un moyen d'obtenir une nouvelle ligne intégrée qui sera interprétée plus tard après que screen l'ait insérée dans votre Shell bash existant. Utilisez "CTL-V, " pour obtenir cette séquence.

Il serait assez facile de créer de simples Shell-Shell pour automatiser cela et mettre les commandes en file d'attente. Ensuite, chaque fois que vous voulez vérifier l'état de votre file d'attente en arrière-plan, vous ré-attachez via :

screen -S queue -r

Techniquement, vous n'avez même pas besoin de nommer votre session d'écran et cela fonctionnera parfaitement, mais une fois que vous y serez habitué, vous voudrez de toute façon en laisser une en cours d'exécution en permanence ;-)

Bien sûr, si vous faites cela, une autre bonne façon de procéder serait de nommer l'un des Windows actuels "file d'attente" et d'utiliser :

screen -S queue -p queue -X stuff "command"

10voto

Il existe un utilitaire que j'ai utilisé avec beaucoup de succès pour le cas d'utilisation que vous décrivez. Récemment, j'ai déplacé mon ordinateur portable principal vers un nouveau matériel, ce qui a impliqué le déplacement de certains fichiers vers un NAS et le reste vers la nouvelle machine.

Voici comment j'ai procédé.

  1. Installez une connexion réseau sur toutes les machines concernées afin qu'elles puissent se joindre les unes aux autres.

  2. Sur la machine à partir de laquelle vous déplacez des fichiers (ci-après appelée machine source), installez rsync à l'aide de la commande apt-get install rsync et la sauce secrète Serveur de tâches (site web http://vicerveza.homeunix.net/~viric/soft/ts/ ). Si vous êtes sous Debian, le nom du paquet pour ts est task-spooler et l'exécutable est renommé en tsp afin d'éviter les conflits de noms avec le ts de l'exécutable de l'application moreutils l'emballage. Le paquet Debian dont le lien figure sur le site web est parfaitement installable sur Ubuntu avec dpkg -i task-spooler_0.7.3-1_amd64.deb ou similaire.

  3. Assurez-vous également que toutes les machines ont installé SSH avec apt-get install openssh-server . Sur la machine source, vous devez configurer SSH pour permettre une connexion sans mot de passe aux machines cibles. La méthode la plus utilisée est l'authentification par clé publique avec ssh-agent (voir https://www.google.se/search?q=ssh+clé+publique+authentification pour des exemples), mais j'utilise parfois une méthode plus simple qui fonctionne tout aussi bien avec l'authentification par mot de passe. Ajoutez ce qui suit à la configuration de votre client SSH (soit ~/.ssh/config o /etc/ssh/ssh_config ) :

    Host *
         ControlMaster auto
         ControlPath ~/.ssh/master-%r@%h:%p

    Ouvrez ensuite un terminal sur la machine source, connectez-vous avec ssh target1 authentifiez vous comme d'habitude, puis laissez ce terminal ouvert. Remarquez qu'il y a un fichier de socket nommé ~/.ssh/master-user@target1:22 Il s'agit du fichier qui maintiendra ouverte une session maître authentifiée et autorisera les connexions ultérieures sans mot de passe pour les sessions user (à condition que la connexion utilise le même nom d'hôte et le même port).

    À ce stade, vous devez vérifier que vous pouvez vous connecter sans être invité à vous authentifier sur les machines cibles.

  4. Exécuter maintenant ts rsync -ave ssh bigfile user@target1: pour un seul fichier ou ts rsync -ave ssh bigdir user@target1: pour un répertoire. Avec rsync, il est important de ne pas inclure de barre oblique à la fin du répertoire ( bigdir par rapport à bigdir/ ) ou rsync supposera que vous vouliez dire l'équivalent de bigdir/* dans la plupart des autres outils.

    Task Spooler renverra l'invite et vous permettra de mettre en file d'attente plusieurs de ces commandes à la suite. Inspectez la file d'attente d'exécution avec ts sans arguments.

Task Spooler possède de nombreuses fonctionnalités telles que la réorganisation de la file d'attente d'exécution, l'exécution d'un travail spécifique uniquement si un autre travail s'est déroulé avec succès, etc. Consultez l'aide avec ts -h . J'inspecte parfois la sortie de la commande pendant qu'elle s'exécute avec ts -c .

Il existe d'autres méthodes pour ce faire, mais pour votre cas d'utilisation, elles incluent toutes le Task Spooler. J'ai choisi d'utiliser rsync via SSH pour préserver l'horodatage des fichiers, ce que la copie via SMB n'aurait pas fait.

4voto

Ken Williams Points 269

J'ai aussi besoin de ce genre de choses assez fréquemment. J'ai écrit un petit utilitaire appelé after qui exécute une commande dès qu'un autre processus est terminé. Il se présente comme suit :

#!/usr/bin/perl

my $pid = shift;
die "Usage: $0 <pid> <command...>" unless $pid =~ /^\d+$/ && @ARGV;

print STDERR "Queueing process $$ after process $pid\n";
sleep 1 while -e "/proc/$pid";
exec @ARGV;

Vous l'exécutez ensuite comme suit :

% command1 arg1 arg2 ...  # creates pid=2853
% after 2853 command2 arg1 arg2 ... # creates pid=9564
% after 9564 command3 arg1 arg2 ...

Le grand avantage de cette approche par rapport à d'autres est que le premier travail n'a pas besoin d'être exécuté d'une manière particulière, vous pouvez suivre n'importe quel processus avec votre nouveau travail.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X