:TITLE: Invocando subprocessos a partir de Tcl - exec, open
;#
;# RCSID: $Header: /home/cvs/TclTutor3/lesson/Tcl_Portuguese/Tcl_Portuguese26.lsn,v 1.1 2008/08/02 12:37:36 clif Exp $
;# Copyright (c) 1995 Clif Flynt
;# 9300 Fleming Rd.
;# Dexter, MI  48130
;# clif@cflynt.com
;# Veja o arquivo "AVISO" com os termos da licença.
;#
;#*********************************************************
;# Portuguese translation: Lucio Agostinho Rocha
;# E-mail: outrosdiasvirao@yahoo.com.br
;# Last update: 12/01/2006
;#*********************************************************
::CMD:: if {([info exists tcl_platform])} {
  switch $tcl_platform(platform) {
    unix        {
                set Tutor(lsn.codeMod) {
		    {regsub -nocase wish [info nameofexecutable] tclsh largv0 }
                    {regsub TCL_INTERP $line $largv0 line}
                    {regsub TEMPDIR $line "/tmp" line}
		    {regsub "wish" $line "tclsh" line}
                }
        }
    windows     {
                set Tutor(lsn.codeMod) {
		    {regsub -nocase wish [info nameofexecutable] tclsh largv0 }
                    {regsub TCL_INTERP $line [file attributes $largv0 -shortname] line}
                    {regsub TEMPDIR $line "C:/temp" line}
		    {regsub "wish" $line "tclsh" line}
                }         
        }
    mac         {
                set Tutor(lsn.codeMod) {
		    {regsub -nocase wish [info nameofexecutable] tclsh largv0 }
                    {regsub TCL_INTERP $line $largv0 line}
		    {regsub "wish" $line "tclsh" line}
		}
                }
    default     {
                puts "I don't recognize the platform: $tcl_platform(platform)"
                puts "Can't set platform specific parameters"
                }
    } 
  }
:LESSON_TEXT_START_LEVEL 0:
As lições até agora lidaram com programação dentro do interpretador Tcl.
Todavia, Tcl também é útil como uma linguagem de script para juntar outros
pacotes.
Para acompanhar esta função, Tcl tem métodos para chamar subprocessos.
<P>
Há duas formas para chamar subprocessos a partir de Tcl:
<UL COMPACT>
<B><LI>open</B> ...... executa um novo programa com a entrada/saída 
conectada a um descritor de arquivo
<B><LI>exec</B> ...... executa um novo programa como um subprocesso
</UL>
<P>A chamada <B>open</B> é a mesma que é usada para abrir um arquivo.
Se o primeiro caracter no argumento do nome do arquivo é um símbolo de
<I>pipe</I> <B>(|)</B>, então open irá tratar o resto do argumento como um
nome de programa, e irá executar aquele programa com a entrada ou
saída conectada a um descritor de arquivo. Um <I>pipe</I> pode ser aberto
para um subprocesso para leitura, escrita, ou ambos.
<P>
Se o <I>pipe</I> é aberto para leitura e escrita você deve estar atento que
os <I>pipes</I> são <I>bufferizados</I>. A saída de um comando <B>puts</B> 
irá ser salva em um <I>buffer</I> de entrada/saída até que o <I>buffer</I>
esteja cheio, ou até você executar um comando <B>flush</B> para forçá-la
a ser transmitida para o subprocesso. A saída do subprocesso não irá
estar disponível para um <B>leitura</B> ou <B>gets</B> até o <I>buffer</I>
de entrada/saída para o subprocesso encher seu <I>buffer</I> de saída.
<P>
A chamada <B>exec</B> é similar a chamar um programa (ou um conjunto
de programas ligados por um <I>pipe</I>) do <I>prompt shell</I> ou
em um <I>shell script</I> unix. Ela suporta muitos estilos de redirecionamento
da saída, ou pode retornar a saída do subprocesso como o retorno da
chamada <B>exec</B>.
<DL>
<B><DT>open |</B><I>nomePrograma ?acesso?</I>
<DD>Retorna um descritor de arquivo para o <I>pipe</I>. O argumento <I>nomePrograma</I> 
deve iniciar com o símbolo <I>pipe</I>. Se <I>nomePrograma</I> estiver
delimitado por aspas duplas ou chaves, ele pode incluir argumentos
para o subprocesso.
<B><DT>exec</B> <I>?modificadores? arg1 ?arg2? ... ?argN?</I>
<DD><B>Exec</B> trata seus argumentos como os nomes e argumentos
para um conjunto de subprocessos a serem executados. Se o primeiro
<I>arg</I> inicia com um <B>"-"</B>, então eles são tratados como
<I>modificadores</I> para o comando exec, ao invés de serem 
chamados como subprocessos ou opções dos subprocessos
<P>
<I>Modificadores</I> são:
<DL>
<B><DT>-keepnewline</B>
<DD> Mantém um caracter de nova linha no início, na saída da linha de <I>pipe</I>.
Normalmente um caracter de nova linha no início será excluído.
<B><DT>--</B>
<DD>Indica o fim dos modificadores. A próxima string será tratada
como <I>arg1</I>, mesmo se ela começar com um <B>"-"</B>
<P>
</DL>
<I>Arg1 - argN</I> podem ser um dos seguintes:
<UL COMPACT>
<LI> o nome de um programa para executar
<LI> um argumento de comando de linha para o subprocesso
<LI> uma instrução de redirecionamento de entrada/saída.
</UL>
Há muitas permutações para os comandos de redirecionamento de
entrada/saída. O principal conjunto desses comandos é:
<DL>
<B><DT> | </B>
<DD> Liga a saída padrão do comando precedente ao símbolo de <I>pipe</I>
na entrada padrão do comando seguinte ao símbolo de <I>pipe</I>.
<B><DT>&lt nomeArquivo</B>
<DD> O primeiro programa no <I>pipe</I> irá ler a entrada de <B>nomeArquivo</B>.
<B><DT> &lt @ IDArquivo</B>
<DD> O primeiro programa no <I>pipe</I> irá ler a entrada do Tcl descritor de
<B>IDArquivo</B>.
<B>IDArquivo</B> é o valor retornado de um comando <B>open ... "r"</B>.
<B><DT> &lt &lt valor</B>
<DD>O primeiro programa no <I>pipe</I> irá ler o <B>valor</B> como sua entrada.
<B><DT>&gt nomeArquivo</B>
<DD> A saída do último programa no <I>pipe</I> irá ser enviada para <B>nomeArquivo</B>.
Qualquer conteúdo anterior de <B>nomeArquivo</B> será perdido.
<B><DT>&gt &gt nomeArquivo</B>
<DD> A saída do último programa no <I>pipe</I> será adicionada no final de <B>nomeArquivo</B>.
<B><DT>2&gt nomeArquivo</B>
<DD> O erro padrão de todos os programas no <I>pipe</I> será enviado para <B>nomeArquivo</B>.
Qualquer conteúdo anterior de <B>nomeArquivo</B> será perdido.
<B><DT>2&gt &gt nomeArquivo</B>
<DD> O erro padrão de todos os programas no <I>pipe</I> será adicionado ao 
final de <B>nomeArquivo</B>.
<B><DT>&gt @ IDArquivo</B>
<DD> A saída do último programa noo <I>pipe</I> será escrita em <B>IDArquivo</B>.
<B>IDArquivo</B> é o valor retornado de um comando <B>open ... "w"</B>.
</DL>
</DL>
:TEXT_END:

:LESSON_TEXT_START_LEVEL 1:
As lições até agora lidaram com programação dentro do interpretador Tcl.
Todavia, Tcl também é útil como uma linguagem de script para juntar outros
pacotes.
Para acompanhar esta função, Tcl tem métodos para chamar subprocessos.
<P>
Há duas formas para chamar subprocessos a partir de Tcl:
<UL COMPACT>
<B><LI>open</B> ...... executa um novo programa com a entrada/saída 
conectada a um descritor de arquivo
<B><LI>exec</B> ...... executa um novo programa como um subprocesso
</UL>
<P>A chamada <B>open</B> é a mesma que é usada para abrir um arquivo.
Se o primeiro caracter no argumento do nome do arquivo é um símbolo de
<I>pipe</I> <B>(|)</B>, então open irá tratar o resto do argumento como um
nome de programa, e irá executar aquele programa com a entrada ou
saída conectada a um descritor de arquivo. Um <I>pipe</I> pode ser aberto
para um subprocesso para leitura, escrita, ou ambos.
<P>
Se o arquivo é aberto para leitura e escrita você deve estar atento que
os <I>pipes</I> são <I>bufferizados</I>. A saída de um comando <B>puts</B> 
irá ser salva em um <I>buffer</I> de entrada/saída até que o <I>buffer</I>
esteja cheio, ou até você executar um comando <B>flush</B> para forçá-la
a ser transmitida para o subprocesso. A saída do subprocesso não irá
estar disponível para um <B>leitura</B> ou <B>gets</B> até o <I>buffer</I>
de entrada/saída para o subprocesso encher seu <I>buffer</I> de saída.
<P>
A chamada <B>exec</B> é similar a chamar um programa (ou um conjunto
de programas ligados por um <I>pipe</I>) do <I>prompt shell</I> ou
em um <I>shell script</I> unix. Ela suporta muitos estilos de redirecionamento
da saída, ou pode retornar a saída do subprocesso como o retorno da
chamada <B>exec</B>.
<DL>
<B><DT>open |</B><I>nomePrograma ?acesso?</I>
<DD>Retorna um descritor de arquivo para o <I>pipe</I>. O argumento <I>nomePrograma</I> 
deve iniciar com o símbolo <I>pipe</I>. Se <I>nomePrograma</I> estiver
delimitado por aspas duplas ou chaves, ele pode incluir argumentos
para o subprocesso.
<B><DT>exec</B> <I>?modificadores? arg1 ?arg2? ... ?argN?</I>
<DD><B>Exec</B> trata seus argumentos como os nomes e argumentos
para um conjunto de subprocessos a serem executados. Se o primeiro
<I>arg</I> inicia com um <B>"-"</B>, então eles são tratados como
<I>modificadores</I> para o comando exec, ao invés de serem 
chamados como subprocessos ou opções dos subprocessos
<P>
<I>Modificadores</I> são:
<DL>
<B><DT>-keepnewline</B>
<DD> Mantém um caracter de nova linha no início, na saída da linha de <I>pipe</I>.
Normalmente um caracter de nova linha no início será excluído.
<B><DT>--</B>
<DD>Indica o fim dos modificadores. A próxima string será tratada
como <I>arg1</I>, mesmo se ela começar com um <B>"-"</B>
<P>
</DL>
<I>Arg1 - argN</I> podem ser um dos seguintes:
<UL COMPACT>
<LI> o nome de um programa para executar
<LI> um argumento de comando de linha para o subprocesso
<LI> uma instrução de redirecionamento de entrada/saída.
</UL>
Há muitas permutações para os comandos de redirecionamento de
entrada/saída. O principal conjunto desses comandos é:
<DL>
<B><DT> | </B>
<DD> Liga a saída padrão do comando precedente ao símbolo de <I>pipe</I>
na entrada padrão do comando seguinte ao símbolo de <I>pipe</I>.
<B><DT>&lt nomeArquivo</B>
<DD> O primeiro programa no <I>pipe</I> irá ler a entrada de <B>nomeArquivo</B>.
<B><DT> &lt @ IDArquivo</B>
<DD> O primeiro programa no <I>pipe</I> irá ler a entrada do Tcl descritor de
<B>IDArquivo</B>.
<B>IDArquivo</B> é o valor retornado de um comando <B>open ... "r"</B>.
<B><DT> &lt &lt valor</B>
<DD>O primeiro programa no <I>pipe</I> irá ler o <B>valor</B> como sua entrada.
<B><DT>&gt nomeArquivo</B>
<DD> A saída do último programa no <I>pipe</I> irá ser enviada para <B>nomeArquivo</B>.
Qualquer conteúdo anterior de <B>nomeArquivo</B> será perdido.
<B><DT>&gt &gt nomeArquivo</B>
<DD> A saída do último programa no <I>pipe</I> será adicionada no final de <B>nomeArquivo</B>.
<B><DT>2&gt nomeArquivo</B>
<DD> O erro padrão de todos os programas no <I>pipe</I> será enviado para <B>nomeArquivo</B>.
Qualquer conteúdo anterior de <B>nomeArquivo</B> será perdido.
<B><DT>2&gt &gt nomeArquivo</B>
<DD> O erro padrão de todos os programas no <I>pipe</I> será adicionado ao 
final de <B>nomeArquivo</B>.
<B><DT>&gt @ IDArquivo</B>
<DD> A saída do último programa noo <I>pipe</I> será escrita em <B>IDArquivo</B>.
<B>IDArquivo</B> é o valor retornado de um comando <B>open ... "w"</B>.
</DL>
</DL>
<P>
Se você está familiarizado com a programação <I>shell</I>, há algumas
diferenças que você precisa tomar cuidado quando estiver escrevendo
scripts Tcl que usam as chamadas <B>exec</B> e <B>open</B>.
<UL COMPACT>
<LI> Você não precisa das aspas duplas que você colocaria 
para delimitar os argumentos para que estes não sejam
expandidos pelo <I>shell</I>. 
<LI> Se você utilizar a construção:
<P>
<B>open |cmd "r+"</B> 
<P>
você deve seguir cada <CODE>puts</CODE> com um comando <CODE>flush</CODE>
para forçar Tcl a enviar o comando de seu <I>buffer</I> para o programa.
A saída do subprocesso pode ser <I>bufferizada</I> em seu <I>buffer</I>
de saída.
<P>
Você pode algumas vezes forçar a saída do subprocesso a ser passada
do espaço da memória (<I>buffer</I>) para o disco enviando um comando
<CODE>exit</CODE> para o processo.
<P> 
Você pode também usar o comando <CODE>fconfigure</CODE> para liberar
um canal da condição de <I>buffer</I>.
<P>
A extensão <B>expect</B> para Tcl fornece uma interface muito melhor
para outros programas, e manipula o problema da <I>bufferização</I>.
<P>
<LI> Se um dos comandos em um <B>open |cmd</B> falhar, o comando <B>open</B>
não retorna um erro. Todavia, a tentativa de ler a entrada do descritor
de arquivos com <B>gets $arquivo</B> irá retornar uma string vazia.
Utilizando a construção <B>gets $arquivo entrada</B> irá retornar um
caracter de contagem igual a -1.
<P>
<LI>Se um dos comandos em uma chamada <B>exec</B> falha ao executar,
o comando <B>exec</B> irá retornar um erro, e a saída do erro irá incluir
a última linha descrevendo o erro.
</UL>
:TEXT_END:

:LESSON_TEXT_START_LEVEL 2:
As lições até agora lidaram com programação dentro do interpretador Tcl.
Todavia, Tcl também é útil como uma linguagem de script para juntar outros
pacotes.
Isso é similar ao comportamento de arquivos .bat do DOS. Como os arquivos
.bat, você pode chamar outros programas a partir de Tcl. O novo programa
é chamado subprocesso.
<P>
Há duas formas para chamar subprocessos a partir de Tcl:
<UL COMPACT>
<B><LI>open</B> ...... executa um novo programa com a entrada/saída 
conectada a um descritor de arquivo
<B><LI>exec</B> ...... executa um novo programa como um subprocesso
</UL>
<P>A chamada <B>open</B> é a mesma que é usada para abrir um arquivo.
Se o primeiro caracter no argumento do nome do arquivo é um símbolo de
<I>pipe</I> <B>(|)</B>, então open irá tratar o resto do argumento como um
nome de programa, e irá executar aquele programa com a entrada ou
saída conectada a um descritor de arquivo. Um <I>pipe</I> pode ser aberto
para um subprocesso para leitura, escrita, ou ambos.
<P>
Muitos sistemas operacionais de computador <I>bufferizam</I> sua entrada
e saída. Isso significa que a string que você enviou para um <B>puts</B> 
pode não ser transmitida imediatamente. Ao invés disso, ela é escrita
em um <I>buffer</I> e quando o <I>buffer</I> estiver cheio (ou o programa
executar um comando <B>flush</B>) a saída é enviada.
Quando esses programas são executados interativamente, eles normalmente
liberam o <I>buffer</I> imediatamente depois de cada saída, mas quando 
eles executam em uma linha de <I>pipe</I> entre outros processos, 
eles <I>bufferizam</I> e montam a saída. Isso é mais eficiente para
o computador.
<P>
Se o arquivo é aberto para leitura e escrita você deve estar atento que
os <I>pipes</I> são <I>bufferizados</I>. A saída de um comando <B>puts</B> 
irá ser salva em um <I>buffer</I> de entrada/saída até que o <I>buffer</I>
esteja cheio, ou até você executar um comando <B>flush</B> para forçá-la
a ser transmitida para o subprocesso. A saída do subprocesso não irá
estar disponível para um <B>leitura</B> ou <B>gets</B> até o <I>buffer</I>
de entrada/saída para o subprocesso encher seu <I>buffer</I> de saída.
<P>
A chamada <B>exec</B> é similar a chamar um programa (ou um conjunto
de programas ligados por um <I>pipe</I>) do <I>prompt shell</I> ou
em um <I>shell script</I> unix. Ela suporta muitos estilos de redirecionamento
da saída, ou pode retornar a saída do subprocesso como o retorno da
chamada <B>exec</B>.
<DL>
<B><DT>open |</B><I>nomePrograma ?acesso?</I>
<DD>Retorna um descritor de arquivo para o <I>pipe</I>. O argumento <I>nomePrograma</I> 
deve iniciar com o símbolo <I>pipe</I>. Se <I>nomePrograma</I> estiver
delimitado por aspas duplas ou chaves, ele pode incluir argumentos
para o subprocesso.
<B><DT>exec</B> <I>?modificadores? arg1 ?arg2? ... ?argN?</I>
<DD><B>Exec</B> trata seus argumentos como os nomes e argumentos
para um conjunto de subprocessos a serem executados. Se o primeiro
<I>arg</I> inicia com um <B>"-"</B>, então eles são tratados como
<I>modificadores</I> para o comando exec, ao invés de serem 
chamados como subprocessos ou opções dos subprocessos
<P>
<I>Modificadores</I> são:
<DL>
<B><DT>-keepnewline</B>
<DD> Mantém um caracter de nova linha no início, na saída da linha de <I>pipe</I>.
Normalmente um caracter de nova linha no início será excluído.
<B><DT>--</B>
<DD>Indica o fim dos modificadores. A próxima string será tratada
como <I>arg1</I>, mesmo se ela começar com um <B>"-"</B>
<P>
</DL>
<I>Arg1 - argN</I> podem ser um dos seguintes:
<UL COMPACT>
<LI> o nome de um programa para executar
<LI> um argumento de comando de linha para o subprocesso
<LI> uma instrução de redirecionamento de entrada/saída.
</UL>
Há muitas permutações para os comandos de redirecionamento de
entrada/saída. O principal conjunto desses comandos é:
<DL>
<B><DT> | </B>
<DD> Liga a saída padrão do comando precedente ao símbolo de <I>pipe</I>
na entrada padrão do comando seguinte ao símbolo de <I>pipe</I>.
<B><DT>&lt nomeArquivo</B>
<DD> O primeiro programa no <I>pipe</I> irá ler a entrada de <B>nomeArquivo</B>.
<B><DT> &lt @ IDArquivo</B>
<DD> O primeiro programa no <I>pipe</I> irá ler a entrada do Tcl descritor de
<B>IDArquivo</B>.
<B>IDArquivo</B> é o valor retornado de um comando <B>open ... "r"</B>.
<B><DT> &lt &lt valor</B>
<DD>O primeiro programa no <I>pipe</I> irá ler o <B>valor</B> como sua entrada.
<B><DT>&gt nomeArquivo</B>
<DD> A saída do último programa no <I>pipe</I> irá ser enviada para <B>nomeArquivo</B>.
Qualquer conteúdo anterior de <B>nomeArquivo</B> será perdido.
<B><DT>&gt &gt nomeArquivo</B>
<DD> A saída do último programa no <I>pipe</I> será adicionada no final de <B>nomeArquivo</B>.
<B><DT>2&gt nomeArquivo</B>
<DD> O erro padrão de todos os programas no <I>pipe</I> será enviado para <B>nomeArquivo</B>.
Qualquer conteúdo anterior de <B>nomeArquivo</B> será perdido.
<B><DT>2&gt &gt nomeArquivo</B>
<DD> O erro padrão de todos os programas no <I>pipe</I> será adicionado ao 
final de <B>nomeArquivo</B>.
<B><DT>&gt @ IDArquivo</B>
<DD> A saída do último programa noo <I>pipe</I> será escrita em <B>IDArquivo</B>.
<B>IDArquivo</B> é o valor retornado de um comando <B>open ... "w"</B>.
</DL>
</DL>
<P>
Se você está familiarizado com a programação <I>shell</I>, há algumas
diferenças que você precisa tomar cuidado quando estiver escrevendo
scripts Tcl que usam as chamadas <B>exec</B> e <B>open</B>.
<UL COMPACT>
<LI> Você não precisa das aspas duplas que você colocaria 
para delimitar os argumentos para que estes não sejam
expandidos pelo <I>shell</I>. 
<LI> Se você utilizar a construção:
<P>
<B>open |cmd "r+"</B> 
<P>
você deve seguir cada <CODE>puts</CODE> com um comando <CODE>flush</CODE>
para forçar Tcl a enviar o comando de seu <I>buffer</I> para o programa.
A saída do subprocesso pode ser <I>bufferizada</I> em seu <I>buffer</I>
de saída.
<P>
Você pode algumas vezes forçar a saída do subprocesso a ser passada
do espaço da memória (<I>buffer</I>) para o disco enviando um comando
<CODE>exit</CODE> para o processo.
<P> 
Você pode também usar o comando <CODE>fconfigure</CODE> para liberar
um canal da condição de <I>buffer</I>.
<P>
A extensão <B>expect</B> para Tcl fornece uma interface muito melhor
para outros programas, e manipula o problema da <I>bufferização</I>.
<P>
<LI> Se um dos comandos em um <B>open |cmd</B> falhar, o comando <B>open</B>
não retorna um erro. Todavia, a tentativa de ler a entrada do descritor
de arquivos com <B>gets $arquivo</B> irá retornar uma string vazia.
Utilizando a construção <B>gets $arquivo entrada</B> irá retornar um
caracter de contagem igual a -1.
<P>
Escreva a string <CODE>Isso irá ser escrito do fim para o início.</CODE> 
apenas como <CODE>Isso</CODE> para ver esse comportamento no exemplo.
<P>
<LI>Se um dos comandos em uma chamada <B>exec</B> falha ao executar,
o comando <B>exec</B> irá retornar um erro, e a saída do erro irá incluir
a última linha descrevendo o erro.
</UL>
<P>
O exemplo de código mostra como usar as chamadas <B>open</B> e <B>exec</B> 
de várias maneiras. Elas não são necessariamente a melhor forma de arquivar
um resultado, mas elas funcionam, Em particular, se você está processando
uma grande quantidade de texto, (e está em um sistema que tem ferramentas
orientadas a texto) é freqüentemente mais rápido para <B>exec</B> trabalhar
com uma cópia do conteúdo e <I>pipe</I> o texto, ao invés de escrever um script Tcl
para fazer o processamento.
<P>
O exemplo começa escrevendo um programa Tcl simples que irá reverter
a ordem dos caracteres para um arquivo temporário. Nós iremos executar
aquele programa em um interpretador Tcl separado para testar a 
leitura e escrita para outro programa.
<P>
Uma vez que o programa é escrito, e o arquivo é fechado, nós podemos
executar aquele script Tcl. O comando:
<P>
<CODE>
set es [open "|/usr/local/bin/tclsh $nomeArqTemp" r+]
</CODE>
<P>
abre um <I>pipe</I> para leitura e escrita para o novo programa. Quando
uma string é escrita para o programa, ela deve ser seguida por um
comando <CODE>flush</CODE> para forçar a string a ser enviada.
<P>
Quando o script Tcl lê uma string de <CODE>stdin</CODE> ele
reverte as letras, as escreve no dispositivo de saída padrão, e termina.
Quando esse programa termina, o <I>buffer</I> é esvaziado, e o exemplo
pode ler a string do canal.
<P>
O exemplo de <CODE>exec</CODE> mostra um método diferente para chamar
o programa exemplo. Uma única linha de entrada pode ser enviada para
outro programa como um único comando Tcl.
:TEXT_END:

:CODE_START:
;# Cria um nome de arquivo único (na maioria das vezes) para um programa Tcl
set nomeArqTemp "TEMPDIR/inv_[pid].tcl"

;# Abre o arquivo de saída e 
;# escreve um programa simples nele

set outfl [open $nomeArqTemp w]

puts $outfl {
    set tamanho [gets stdin linha]
    if {$tamanho < 5} {exit -1}

    for {set i $tamanho} {$i >= 0} {incr i -1} {
        append l2 [string range $linha $i $i]
    }
    puts $l2
    exit 0
}

# Libera da memória para o disco e fecha o arquivo
flush $outfl
close $outfl

# Executa o novo arquivo Tcl interativamente

# Abre um pipe para o programa - es = entrada/saída
set es [open "|TCL_INTERP $nomeArqTemp" r+]

# Envia uma string para o novo programa
#     *PRECISA DO COMANDO FLUSH*
puts $es "Isso irá ser escrito do fim para o início."
flush $es

# Adquire o retorno, e o exibe.

set tamanho [gets $es linha]

puts  "Para reverter: 'Isso irá ser escrito do fim para o início.'"
puts "Revertida é: $linha"
puts "A linha tem $tamanho caracteres"

# Executa o programa com a entrada definida em uma chamada exec

set inverter [exec TCL_INTERP $nomeArqTemp << \
	"SUBI NO ON IBUS"]

# Exibe o resultado
puts "A inversão de 'SUBI NO ON IBUS' é '$inverter'"

# Limpa tudo
file delete $nomeArqTemp
:TEXT_END:
