10
votes

Comment puis-je rediriger stdout dans un fichier dans TCL

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"

tcl

0 commentaires

7 Réponses :


1
votes

actuellement lorsque vous tapez 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.

Vous pouvez rediriger au niveau supérieur, alors lorsque vous exécutez TCLSH TCLSH> bar code> alors toute la sortie sera redirigée, mais je doute. C'est ce que vous voulez. P>

Vous pouvez changer de FOO afin qu'il accepte un fichier ouvert comme paramètre et écrivez à celui-ci: p>

proc foo {fp} {
   puts $fp "some text"
}

set fp [open bar w]
foo $fp
close $fp


0 commentaires

6
votes

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:


0 commentaires

3
votes

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.

dans ces cas que vous pouvez Essayez de redéfinir la commande met . 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. xxx

Vous pouvez également rediriger Texte dans une variable: xxx

Le wiki TCL'ers a un autre Exemple intéressant de redéfinir met dans des applications plus complexes. Peut-être que cela est également inspirant.


0 commentaires

5
votes

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
% 


0 commentaires

1
votes

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: xxx

fichier - foo.csh (n'importe quel script shell fonctionnera, je suis en utilisant csh pour cet exemple): Entrez le code ici xxx

fichier - main.tcl: xxx

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.


0 commentaires

1
votes

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
}


0 commentaires

1
votes

Nous pouvons essayer de cette manière aussi xxx


0 commentaires