Comment puis-je rediriger une sortie PROC dans un fichier dans TCL, par exemple, j'ai un processus de FOO et souhaitez rediriger la sortie FOO dans une barre de fichiers. Mais obtenu ce résultat
% proc foo {} { puts "hello world" } % foo hello world % foo > bar wrong # args: should be "foo"
7 Réponses :
actuellement lorsque vous tapez Vous pouvez rediriger au niveau supérieur, alors lorsque vous exécutez TCLSH Vous pouvez changer de FOO afin qu'il accepte un fichier ouvert comme paramètre et écrivez à celui-ci: p> foo> bar code> TCL essaie d'exécuter une procédure FOO qui prend 2 paramètre, car cela n'existe pas, vous obtenez le message d'erreur. Je peux penser à deux façons que vous pourriez aborder ce problème.
TCLSH> bar code> alors toute la sortie sera redirigée, mais je doute. C'est ce que vous voulez. P>
proc foo {fp} {
puts $fp "some text"
}
set fp [open bar w]
foo $fp
close $fp
Si vous ne pouvez pas modifier votre code pour prendre le nom d'un canal pour écrire à (la solution la plus robuste), vous pouvez utiliser une astuce pour rediriger stdout code> dans un fichier: réouverture .
proc foo {} { puts "hello world" }
proc reopenStdout {file} {
close stdout
open $file w ;# The standard channels are special
}
reopenStdout ./bar
foo
reopenStdout /dev/tty ;# Default destination on Unix; Win equiv is CON:
En règle générale, je recommanderais la redirection de stdouts que les boursiers donaux suggèrent dans sa réponse .
Parfois, cela peut parfois pas possible. Peut-être que l'interprète TCL est liée à une application complexe qui a elle-même une idée fantaisie de l'endroit où la sortie devrait aller à, puis vous ne savez pas comment restaurer le canal stdout. P>
dans ces cas que vous pouvez Essayez de redéfinir la commande Vous pouvez également rediriger Texte dans une variable: p> Le wiki TCL'ers a un autre Exemple intéressant de redéfinir met code>. Voici un exemple de code sur la façon dont vous pourriez le faire. En plain TCL, une commande peut être redéfinie par renommer IT dans un nom de sécurité et créant un processus d'enveloppe qui appelle la commande d'origine au nom de sécurité - ou pas du tout, en fonction de la fonctionnalité souhaitée. p>
met code>
dans des applications plus complexes. Peut-être que cela est également inspirant. P> p>
Cela devrait fonctionner:
% proc foo {} { return "hello world" } % foo hello world % exec echo [foo] > bar % exec cat bar hello world % exec echo [foo] >> bar % exec cat bar hello world hello world %
Pour accomplir cela, j'ai enveloppé l'appel à mon procédé TCL dans un script shell. Cela fonctionne sur UNIX, pas sûr d'un autre système d'exploitation.
fichier - foo.tcl: p> fichier - foo.csh (n'importe quel script shell fonctionnera, je suis en utilisant csh pour cet exemple):
fichier - main.tcl: p> bien sûr ces commandes Peut être fait de «fantaisie» en les enveloppant dans des mesures de sécurité telles que Catch, etc. pour la clarté, je ne les ai pas inclus, mais je recommanderais leur utilisation. Aussi, j'ai inclus $ ARGV qui n'est pas nécessaire car procès ne prend pas arguments, mais généralement IRL, il y aura des arguments. Assurez-vous d'utiliser >> si vous souhaitez simplement ajouter au fichier plutôt que de l'écraser. P> p> Entrez le code ici code> p>
Merci d'avoir partagé CFI. Je voudrais aussi contribuer aussi. Ainsi, j'ai apporté des modifications à redéfinir les puts sur Dump to File sur StartLog et terminez la journalisation sur endlog au fichier lorsque nous voulons. Ceci imprimera sur stdout et redirigera également stdout à fichier.
proc startlog {filename } { rename puts ::tcl::orig::puts set mode w global def destination logfilename set destination [open $filename $mode] set logfilename $filename proc puts args " uplevel 2 \"::tcl::orig::puts \$args\" uplevel \"::tcl::orig::puts $destination \{\$args\}\"; return " } proc endlog { } { global def destination logfilename close $destination rename puts {} rename ::tcl::orig::puts puts cleanlog $logfilename puts "name of log file is $logfilename" } proc cleanlog {filename } { set f [open $filename] set output [open $filename\.log w] set line1 [regsub -all {\-nonewline stdout \{} [read $f] ""] set line2 [regsub -all {stdout \{} $line1 ""] set line3 [regsub -all {\}} $line2 ""] set line4 [regsub -all {\{} $line3 ""] puts $output $line4 close $output file rename -force $filename.log $filename }
Nous pouvons essayer de cette manière aussi