Je dois beaucoup copier de divers fichiers dans différents dossiers. Je peux ajouter toutes mes commandes de copie à un script bash, puis l'exécuter, mais je dois attendre jusqu'à ce que l'opération se termine si je veux ajouter d'autres commandes à cette "file" de copie.
Est-il possible d'exécuter des commandes en tant que file d'attente et d'ajouter d'autres commandes à cette file d'attente pendant le fonctionnement?
Expliqué d'une manière différente, je veux démarrer une tâche longue. Pendant que cela fonctionne, je veux en lancer un autre qui ne démarre réellement que lorsque le premier est terminé. Et puis ajoutez un autre après ce dernier et ainsi de suite. Est-ce possible d'une certaine manière?
Réponses:
L'
at
utilitaire, mieux connu pour l'exécution de commandes à une heure précise, possède également une fonction de file d'attente et peut être invité à démarrer l'exécution de commandes maintenant. Il lit la commande à exécuter à partir de l'entrée standard.La
batch
commande est équivalente àat -q b -m now
(-m
ce qui signifie que le résultat de la commande, le cas échéant, vous sera envoyé, comme le fait cron). Toutes les variantes Unix ne prennent pas en charge les noms de file d'attente (-q myqueue
); vous pouvez être limité à une seule file d'attente appeléeb
. Linuxat
est limité aux noms de file d'attente d'une seule lettre.la source
now
, non-t now
, désolé. Je n'avais pas remarqué que j'avais tort dans l'exemple de code.Ajoutez
&
à la fin de votre commande pour l'envoyer en arrière-plan, puiswait
sur avant de lancer la suivante. Par exemple:la source
wait
? Il semble insensible à tous mes coups de feu.wait
simplement arrête le travail jusqu'à la fin des précédentsnohup
?Les solutions de Brad et Mankoff sont toutes deux de bonnes suggestions. Une autre combinaison semblable à une combinaison des deux consisterait à utiliser GNU Screen pour implémenter votre file d'attente. Cela présente l’avantage de pouvoir s’exécuter en arrière-plan. Vous pouvez le vérifier à tout moment et les mettre en file d’attente de nouvelles commandes ne fait que les coller dans la mémoire tampon à exécuter après la fermeture des commandes précédentes.
Première exécution:
(accessoirement, le moment est venu de jouer avec des fichiers géniaux. screenrc )
Cela créera une session d'écran en arrière-plan pour votre file d'attente nommée.
Maintenant, mettez en file d'attente autant de commandes que vous le souhaitez:
Je fais plusieurs commandes dans ce qui précède juste pour les tests. Votre cas d'utilisation ressemblerait probablement davantage à:
Notez que le "^ M" dans ma ligne ci-dessus est un moyen d’obtenir une nouvelle ligne incorporée qui sera interprétée plus tard après que l’écran l’a 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 scripts shell pour automatiser cela et mettre les commandes en file d'attente. Ensuite, chaque fois que vous souhaitez vérifier l'état de votre file d'attente en arrière-plan, vous vous reconnectez via:
Techniquement, vous n'avez même pas besoin de nommer votre session écran et cela fonctionnera bien, mais une fois que vous y êtes accroché, vous voudrez toujours en laisser une en cours d'exécution tout le temps. ;-)
Bien sûr, si vous faites cela, un autre bon moyen de le faire serait de nommer l’une des "files" de windows actuelles et d’utiliser:
la source
Il existe un utilitaire que j'ai utilisé avec un grand succès pour le cas d'utilisation que vous décrivez. Récemment, j'ai transféré mon ordinateur portable principal sur un nouveau matériel, ce qui impliquait le transfert de certains fichiers sur un NAS et le reste sur la nouvelle machine.
Voici comment je l'ai fait.
Configurez toutes les machines impliquées avec une connexion réseau afin qu'elles puissent se joindre.
Sur la machine à partir de laquelle vous déplacez des fichiers (ci-après appelée machine source), installez rsync avec
apt-get install rsync
et le spool de tâches secret-sauce (site Web http://vicerveza.homeunix.net/~viric/soft/ts/ ). Si vous êtes sur Debian, le nom du paquetts
est istask-spooler
et l'exécutable est renommé afintsp
d'éviter tout conflit de nom avec l'ts
exécutable dumoreutils
paquet. Le paquet Debian lié au site Web est parfaitement installable sur Ubuntu avecdpkg -i task-spooler_0.7.3-1_amd64.deb
ou similaire.Assurez-vous également que SSH est installé sur toutes les machines
apt-get install openssh-server
. Sur la machine source, vous devez configurer SSH pour permettre la connexion sans mot de passe aux machines cibles. La méthode la plus utilisée est l’authentification par clé publiquessh-agent
(voir https://www.google.se/search?q=ssh+public+key+authentication pour des exemples), mais j’utilise parfois une méthode plus simple qui fonctionne simplement. aussi bien avec authentification par mot de passe. Ajoutez les éléments suivants à la configuration de votre client SSH (~/.ssh/config
ou bien/etc/ssh/ssh_config
):Ouvrez ensuite un terminal sur la machine source, connectez-vous avec
ssh target1
, authentifiez-vous comme d'habitude, puis laissez ce terminal ouvert. Notez qu'il existe un fichier de socket nommé~/.ssh/master-user@target1:22
. Il s'agit du fichier qui gardera une session maître authentifiée ouverte et autorisera les connexions sans mot de passe ultérieuresuser
(tant que la connexion utilise les mêmes nom d'hôte et port cibles).À ce stade, vous devez vérifier que vous pouvez vous connecter sans être invité à vous authentifier auprès des ordinateurs cibles.
Maintenant, exécutez
ts rsync -ave ssh bigfile user@target1:
pour un seul fichier outs rsync -ave ssh bigdir user@target1:
pour un répertoire. Avec rsync, il est important de ne pas inclure de barre oblique finale dans le répertoire (bigdir
par rapport àbigdir/
), sinon rsync supposera que vous entendiez l'équivalent de labigdir/*
plupart des autres outils.Le spouleur de tâches renverra l'invite et vous permettra de mettre en file d'attente plusieurs de ces commandes. Inspectez la file d'attente avec
ts
sans arguments.Le spouleur de tâches possède de nombreuses fonctionnalités telles que la réorganisation de la file d'attente, l'exécution d'un travail spécifique uniquement si un autre travail a été exécuté avec succès, etc. Consultez l'aide avec
ts -h
. J'inspecte parfois la sortie de la commande pendant son exécutionts -c
.Il existe d'autres méthodes pour ce faire, mais pour votre cas d'utilisation, elles incluent toutes le spouleur de tâches. J'ai choisi d'utiliser rsync sur SSH pour préserver les horodatages des fichiers, ce que la copie sur SMB n'aurait pas.
la source
ts
, qui semble très puissant et facile à utiliser, mais que je viens de bifurquer sur github autotoolized et debianized.task-spooler
:-) ... de toute façon, c'est dans votre commentaire, c'est une très bonne suggestion, je le ferai très bientôt.J'ai besoin de trucs comme ça assez souvent aussi. J'ai écrit un petit utilitaire appelé
after
qui exécute une commande lorsqu'un autre processus est terminé. Cela ressemble à ceci:Vous le lancez alors comme ceci:
Le gros avantage de cette approche par rapport à d’autres approches est que le premier travail n’a pas besoin d’être exécuté de manière particulière, vous pouvez suivre n’importe quel processus avec votre nouvel emploi.
la source
Command1 && Command2
la source
Vous pouvez simplement ajouter des commandes à la ligne de commande du shell qui exécute déjà une commande.
Tapez avec soin ou tapez-le ailleurs, vérifiez et copiez-collez. Même si la commande en cours crache des lignes de sortie, vous pouvez toujours taper quelque chose de nouveau, appuyer sur entrée et elle sera exécutée lorsque toutes les commandes seront exécutées ou entrées avant la fin.
L'exemple suit. Vous pouvez couper et coller le tout, ou entrer les commandes suivantes pendant que la 1re est en cours d'exécution (si vous tapez très vite), ou plus probablement pendant que la 2e est en cours d'exécution .:
la source
La façon la plus commode de penser est de maintenir "l'état" de la file d'attente avec de simples fichiers de verrouillage dans / tmp. Lorsque file1.sh exécute ses commandes cp, il conservera un fichier de verrouillage (ou lien dur) dans / tmp. quand c'est fait, effacez le fichier. Tous les autres scripts devront rechercher dans le fichier / tmp les fichiers verrouillés avec le schéma de nommage choisi. Naturellement, cela est sujet à toutes sortes d'échecs, mais son installation est triviale et tout à fait réalisable au sein de Bash.
la source