LINUX.ORG.RU

[tcl]перенаправление вв/вывода дочернего процесса

 


0

0

Задача отправлять команды программе на вход и считывать ее выход.
Нашел пример.

set fd8 [open "| tee tmp/in | simple2 | tee tmp/out 2>tmp/err" r+]

Вопрос
Нет ли решения по-элегантнее?
А еще хотелось бы отлавливать событие завершения подчиненного процесса.


Нет ли решения по-элегантнее?

по каким критериям оценивать элегантность?

http://www.tcl.tk/man/tcl/tutorial/Tcl26.html

отлавливать событие завершения подчиненного процесса

open, fileevent. создаёшь pipe на интересующий тебя процесс и мониторишь его

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

>по каким критериям оценивать элегантность?

в идеале мне хотелось бы кроссплатформенности.
нельзя ли обойтись без вспомогательных процессов и именованных каналов?
хотя может в msys или cygwin это есть — не проверял

и еще
как ввод дочернему процессу передавать? тоже через канал?

zensey
() автор топика
Ответ на: комментарий от zensey

в идеале мне хотелось бы кроссплатформенности

http://wiki.tcl.tk/1039

Here is a TCL implementation that works for UNIX and WIN32 environments. It's done by starting the command in a pipe

нельзя ли обойтись без вспомогательных процессов и именованных каналов?

смотри ссылку выше

как ввод дочернему процессу передавать? тоже через канал?

ну это уже от тебя зависит, я ж не знаю чего тебе надо

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

http://wiki.tcl.tk/1039

Очень заинтересовал последний листинг по данной ссылке.

foreach chan {stdin stdout stderr} {
    lassign [chan pipe] rd$chan wr$chan
} 
set pids [exec {*}$pipeline <@ $rdstdin >@ $wrstdout 2>@ $wrstderr &]
puts $wrstdin "input text to send to pipeline stdin"
puts "received stdout [gets $rdstdout]"
puts "received stderr [gets $rdstderr]"

Что такое {*}$pipeline ? В него-то и надо подставить имя дочерней программы?

zensey
() автор топика
Ответ на: комментарий от jtootf

ладно,
а если я подставлю именованные каналы — прокатит?
тогда можно будет обойтись без tee ?

zensey
() автор топика
Ответ на: комментарий от jtootf

Почти что получилось

На вывод работает.
Но не могу передать ничего на ввод — пайп $p0w

package require Tclx

lassign [pipe] p0r p0w
lassign [pipe] p1r p1w
lassign [pipe] p2r p2w

set pids [exec "cat" <@ $p0r >@ $p1w 2>@ $p2w &]

fileevent $p1r readable got_stdout
fileevent $p2r readable got_stderr

puts $p0w "input text"
puts $p0w "input text"

proc got_stdout {} {
    puts [gets $::p1r]
}
proc got_stderr {} {
    puts [gets $::p2r]
}

zensey
() автор топика
Ответ на: комментарий от zensey

Теперь cat отзывается, а вот wc упрямится. Не знаю что и делать прям.

package require Tclx

lassign [pipe] p0r p0w
lassign [pipe] p1r p1w
lassign [pipe] p2r p2w

fconfigure $p0r -buffering line
fconfigure $p0w -buffering line

set pids [exec "cat" <@ $p0r >@ $p1w 2>@ $p2w &]

fileevent $p1r readable "got_stdout $p1r"
fileevent $p2r readable "got_stderr $p2r"

puts $p0w "qweqweqwe"
puts $p0w "qweqweqwe"
close $p0w
close $p0r

proc got_stdout f {
    puts [gets $f]
}
proc got_stderr f {
    puts [gets $f]
}
zensey
() автор топика
Ответ на: комментарий от zensey

> в идеале мне хотелось бы кроссплатформенности.

нельзя ли обойтись без вспомогательных процессов и именованных каналов?

QProcess

PayableOnDeath
()

чё-то вроде

package require expect
spawn "tee tmp/in | simple2 | tee tmp/out 2>tmp/err"
send "hello"
expect {
  "sam hello" {
     oh_i_nihrena
  }
  timeout {
     net_ni_figa
  }  
  * {
     priperlo $expect_out(buffer)
  }
}

и так далее.

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

перенаправление работает и в том примере что привел, при том даже без именованных каналов.

вопрос только в одном — как сказать wc, что входных данных больше нет.
пайп закрыт, он знай себе продолжает ожидать ввод.
ничего не понимаю.

zensey
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.