Я пытаюсь написать сценарий ожидания, который реагирует на ввод данных при чтении канала. Рассмотрите этот пример в файле "contoller.sh":
#!/usr/bin/env expect
spawn bash --noprofile --norc
set timeout 3
set success 0
send "PS1='Prompt: '\r"
expect {
"Prompt: " { set success 1 }
}
if { $success != 1 } { exit 1 }
proc do { cmd } {
puts "Got command: $cmd"
set success 0
set timeout 3
send "$cmd\r"
expect {
"Prompt: " { set success 1 }
}
if { $success != 1 } { puts "oops" }
}
set cpipe [open "$::env(CMDPIPE)" r]
fconfigure $cpipe -blocking 0
proc read_command {} {
global cpipe
if {[gets $cpipe cmd] < 0} {
close $cpipe
set cpipe [open "$::env(CMDPIPE)" r]
fconfigure $cpipe -blocking 0
fileevent $cpipe readable read_command
} else {
if { $cmd == "exit" } {
exp_close
exp_wait
exit 0
} elseif { $cmd == "ls" } {
do ls
} elseif { $cmd == "pwd" } {
do pwd
}
}
}
fileevent $cpipe readable read_command
vwait forever;
Предположим, вы делаете:
export CMDPIPE=~/.cmdpipe
mkfifo $CMDPIPE
./controller.sh
Теперь из другого терминала попробуйте:
export CMDPIPE=~/.cmdpipe
echo ls >> ${CMDPIPE}
echo pwd >> ${CMDPIPE}
В первом терминале строки "Got command: ls / pwd" печатаются сразу же, как только вы нажимаете enter для каждой команды echo, но нет вывода из порожденной оболочки bash (без списка файлов и текущего каталога). Теперь попробуйте еще раз:
echo ls >> ${CMDPIPE}
Внезапно появляется вывод из первых двух команд, но третья команда (вторая ls) не видна. Продолжайте, и вы заметите, что в отображаемом выводе есть «лаг», который кажется «буферизованным», а затем сразу же сбрасывается.
Почему это происходит и как я могу это исправить?