🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.tcl
2 messages
2 total messages Started by Maciej Sobczak Mon, 03 Oct 2005 14:03
Potok
#182
Author: Maciej Sobczak
Date: Mon, 03 Oct 2005 14:03
24 lines
1407 bytes
Witam,

Czy ktoś z grupowiczów może pomóc z potokiem read-write?

Prosty test:

set pipe [open "|cat" "r+"]
puts $pipe "Hello"
set line [gets $pipe]
puts $line
close $pipe


Otwieram potok z poleceniem cat (któro wypisuje na stdout to, co 
przeczytało na stdin). Piszę do potoku i spodziewam się przeczytać to samo.
Efekt - program nic nie wypisuje i w ogóle nie kontaktuje (Linux).

Krok drugi: potok, w którym można nie tylko pisać do stdin dziecka, ale 
też odczytać *osobno* jego stdout i stderr.


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/
Re: Potok
#183
Author: Maciej Sobczak
Date: Mon, 03 Oct 2005 15:04
66 lines
2891 bytes
Maciej Sobczak wrote:

> Czy ktoś z grupowiczów może pomóc z potokiem read-write?
> 
> Prosty test:
> 
> set pipe [open "|cat" "r+"]
> puts $pipe "Hello"
> set line [gets $pipe]
> puts $line
> close $pipe
> 
> 
> Otwieram potok z poleceniem cat (któro wypisuje na stdout to, co 
> przeczytało na stdin). Piszę do potoku i spodziewam się przeczytać to samo.
> Efekt - program nic nie wypisuje i w ogóle nie kontaktuje (Linux).

Bo kanał I/O jest buforowany. Wystarczyło zrobić flush zaraz po puts.

Człowiek miewa różne zaćmienia. :)

> Krok drugi: potok, w którym można nie tylko pisać do stdin dziecka, ale 
> też odczytać *osobno* jego stdout i stderr.

OK, rozpracowane. Wrzucam tu, może się komuś przyda:

Polecenie exec pozwala przekierowywać wszystkie kanały wywołanego 
programu w dowolne miejsca, również do kanałów, które już są dostępne w 
programie Tcl. Idea polega na tym, żeby najpierw zrobić sobie w 
programie trzy kanały i użyć je w przekierowaniu w uruchamianym 
programie (przy okazji robię też fconfigure, żeby nie trzeba było robić 
flush po każdym zapisie do potoku):


# tworzymy sobie 3 sztuczne kanały I/O:
set pipe_in [open "|cat" "r+"]
fconfigure $pipe_in -buffering line
set pipe_out [open "|cat" "r+"]
set pipe_err [open "|cat" "r+"]

# odpalamy zewnętrzny program:
exec jakisprogram <@ $pipe_in >@ $pipe_out 2>@ $pipe_err &

# piszemy do potoku:
puts $pipe_in "Hello"

# i czytamy co wypluł, *osobno* jego stdout i stderr
# (oczywiście, te polecenia mogą blokować)
set line_from_out [gets $pipe_out]
set line_from_err [gets $pipe_err]

# ...

# finito (zakładamy, że program skończy się po otrzymaniu EOF):
close $pipe_in
close $pipe_out
close $pipe_err


Uwaga: ampersand na końcu exec jest potrzebny, żeby można było dalej 
działać równocześnie z uruchomionym właśnie programem.


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads