Нарушение условия в конструкции If - PullRequest
0 голосов
/ 26 июня 2019

Привет! Я использую этот кусок кода для вставки канала в TCL.Может кто-нибудь, пожалуйста, дайте мне понять, когда это условие [gets $pipe line] >= 0 не выполняется.Например: только когда [gets $pipe line] является отрицательным числом, это не удастся.

В моем случае это никогда не возвращает отрицательное число, и TestEngine зависает навсегда

set pipeline [open "|Certify.exe filename" "r+"]
fileevent $pipeline readable [list handlePipeReadable $pipeline]
fconfigure $pipeline -blocking 0

proc handlePipeReadable {pipe} {
    if {[gets $pipe line] >= 0} {
        # Managed to actually read a line; stored in $line now
    } elseif {[eof $pipe]} {
        # Pipeline was closed; get exit code, etc.
        if {[catch {close $pipe} msg opt]} {
            set exitinfo [dict get $opt -errorcode]
        } else {
            # Successful termination
            set exitinfo ""
        }
        # Stop the waiting in [vwait], below
        set ::donepipe $pipe
    } else {
        puts ""
        # Partial read; things will be properly buffered up for now...
    }
}

vwait ::donepipe

Ответы [ 6 ]

1 голос
/ 27 июня 2019

CMD Prompt screen after running the test engine

Пожалуйста, найдите способ запуска процесса сертификации из командной строки, а операторы печати приведены только для понимания. В конце процесс зависает, и управление не передается обратно в TCL

1 голос
/ 26 июня 2019

Команда gets (когда передается переменная для получения строки) возвращает отрицательное число, когда она находится в состоянии незначительной ошибки.Существует два таких условия:

  1. Когда канал достиг конца файла. После команда gets, eof (примененная к каналу) сообщит об истинном значении в этом случае.
  2. Когда канал заблокирован, т.е.когда он имеет несколько байтов, но не завершенную строку (Tcl имеет внутреннюю буферизацию для обработки этого; вы можете получить число ожидающих байтов с помощью chan pending).Вы видите это только когда канал находится в неблокирующем режиме (потому что в противном случае gets будет ждать бесконечно).В этом случае команда fblocked (применяемая к каналу) вернет true.

Условия серьезных ошибок (например, закрытие канала) приводят к ошибкам Tcl.


Если другая команда производит только частичный вывод или делает что-то странное с буферизацией, вы можете получить вечно заблокированный конвейер.Это более вероятно для двунаправленного канала, такого как вы используете, так как команда Certify, вероятно, ожидает, когда вы закроете другой конец.Вы можете использовать его только для чтения?Существует много сложностей для правильного взаимодействия с процессом в двух направлениях!(Например, вы, вероятно, хотите, чтобы режим буферизации output канала был небуферизованным, fconfigure $pipeline -buffering none.)

0 голосов
/ 28 июня 2019

Пожалуйста, смотрите проблему при запуске с помощью исполняемых аргументов exec &

0 голосов
/ 28 июня 2019

Вы можете увидеть это в CMD с упомянутым скриншотом. Есть ли обходной путь, который мне нужно преодолеть?

0 голосов
/ 27 июня 2019

Ваш скрипт работает полностью нормально. проверил set pipeline [open "|du /usr" "r+"] вместо вашей трубы и включил puts "Line: $line", чтобы проверить результат. Итак, ясно, что в команде Certify есть какая-то проблема. Можете ли вы поделиться своей командой, как вы используете на терминале и как вы использовали с exec?

################### edited by Drektz
set pipeline [open "|du /usr" "r+"]
fileevent $pipeline readable [list handlePipeReadable $pipeline]
fconfigure $pipeline -blocking 0

proc handlePipeReadable {pipe} {
    if {[gets $pipe line] >= 0} {
        # Managed to actually read a line; stored in $line now
################### included by Drektz
puts "Line: $line"
    } elseif {[eof $pipe]} {
        # Pipeline was closed; get exit code, etc.
        if {[catch {close $pipe} msg opt]} {
            set exitinfo [dict get $opt -errorcode]
        } else {
            # Successful termination
            set exitinfo ""
        }
        # Stop the waiting in [vwait], below
        set ::donepipe $pipe
    } else {
        puts ""
        # Partial read; things will be properly buffered up for now...
    }
}

vwait ::donepipe
0 голосов
/ 26 июня 2019

Из документации для получения :

Если указано varName и в varName возвращается пустая строка из-за конца файла или из-за недостатка данных в неблокирующем режиме, то счетчик возврата равен -1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...