2016-09-17 1 views
0

J'ai un script tcl mais qui ne peut décompresser qu'une chose à la fois. Je dois actuellement attendre le moment où il a fini, avant que je puisse faire le prochain. Comment puis-je faire deux choses à la fois?Unrar et unzip simultanément

bind pubm - "*complete*" unrar 

proc unrar {nick host handle channel text} { 
    set text [stripcodes bcru $text] 
    set name [lindex [split $text] 2]; 
    set dir "/tmp/unrar" 
    if {[catch {exec /bin/sh -c "unrar e $dir/$name $dir/archive/$name"} error]} { 
     putlog "error: $error"; 
    } 
} 

Cordialement

+0

D'où vient le décompresseur? N'apparaît pas dans votre code. –

+0

j'ai dans $ nom fichiers .rar et .zip, et si unrar décompresser ce, le problème n'est pas le rar ou zip, est simultanément mon problème, salutations –

Répondre

1

Tcl peut faire plusieurs choses à la fois, surtout quand il se sera d'E/S lié tout en faisant l'attente. Pour ce faire, nous devons tirer parti du fait que eggdrop (je reconnais ce type de bind) exécute la boucle d'événements et utilise la commande fileevent. La commande fileevent est géniale car elle nous permet de programmer du code à exécuter lorsque "quelque chose se passe" sur un canal; quand le canal est un pipeline (ou socket) quand peut utiliser un événement lisible pour faire quelque chose quand il y a du texte à lire ou le canal est fermé. (La différence est difficile à distinguer jusqu'à ce que vous ayez réellement lu quelque chose.)

Mettons les bits ensemble: pipelines et retour des résultats. Je présente la commande asyncpipe! OK, c'est construire la machinerie de base, mais ce n'est pas encore clair pour le moment. Voici comment l'utiliser.

bind pubm - "*complete*" unrar 

proc unrar {nick host handle channel text} { 
    set text [stripcodes bcru $text] 
    set name [lindex [split $text] 2]; 
    set dir "/tmp/unrar" 
    asyncpipe [list unrar e $dir/$name $dir/archive/$name] \ 
     [list unrar.report putlog $name] [list unrar.done $name] 
} 
proc unrar.report {name line} { 
    putlog "unrar $name :>> $line" 
} 
proc unrar.done {name} { 
    putlog "all done with unrar $name" 
} 

Cette rapportera la sortie de unrar comme il arrive et il vous permettra d'exécuter deux à la fois. (Écrire une "copie" qui utilise unzip à la place est laissé comme un exercice, c'est un travail de couper-n-coller sauf peut-être pour les arguments à décompresser.) La programmation asynchrone est un peu plus compliqué que ce à quoi vous êtes habitué , mais tant que vous utilisez des procédures nommées pour les rappels, vous pouvez travailler sans être trop confus. Ignorer les machines et se concentrer sur ce qui se passe au niveau supérieur. Le unrar réécrit analyse ses arguments et demande unrar de s'exécuter de manière asynchrone en tant que sous-processus. Chaque fois qu'il y a sortie, il est déclenché dans unrar.report (une ligne à la fois) qui l'écrit dans le journal. Vous voudrez peut-être le signaler ailleurs/à la place. Lorsque le pipeline se termine, unrar.done est appelé afin qu'il puisse se connecter qu'il est terminé. Je passe le nom en unrar.report et unrar.done car alors il est possible de voir ce que est terminé; sachant ce qui se passe est parfois un problème avec les programmes asynchrones, donc cela aide à être exact. (C'est un vrai pourboire!)

Vous pouvez lancer des choses autant de fois que vous le souhaitez. Faites-en trop (combien dépend de votre matériel) et votre ordinateur va ralentir, peut-être un lot, mais il finira par rattraper son retard.

+0

Bonjour, double unrar travail, après déballer avoir 2 Proc [unrar] , et pas de sortie de putlog unrar.report et unrar.done –

+0

je l'ai édité de [liste unrar.report putlog $ name] à [liste unrar.report $ name] –

+0

travaille maintenant perfekt, big thx Donal Fellows –