команда кошки в оболочке не завершается на receving EOT через последовательный порт

[112152]Избегайте сортировки, используя:

Function Out-Clipboard{
    param($Value,[switch]$PassThru) 
    begin {
            [void][reflection.assembly]::LoadWithPartialName("Windows.Forms")
        $tb = New-Object System.Windows.Forms.TextBox
        $tb.Multiline = $true
        $pipeObjects = @()
    }
    process {
      $pipeObjects+=$_
    }
    end {
        if([string]::IsNullOrEmpty($Value)){
            $text=$null
            $pipeObjects | out-string -stream | %{$text = $text + $(if($text -ne $null){"`r`n"}) + $_}
            $tb.text = $text
        } 
        else {
            $tb.text = $value
        }
        $tb.SelectAll()
        $tb.Copy()
        if($PassThru){
            $pipeObjects
        }
        $tb.Dispose()
    }
}

Или, эквивалентно:

Get-Process | Out-Clipboard

2
03.04.2015, 17:37
2 ответа

CTRL + D здесь бессмысленен - ​​это просто еще один байт. Это потому, что ваш последовательный терминал не настроен для его обработки. В частности, вы фактически находитесь в необработанном режиме или в неканоническом режиме ввода . См. Флаг -icanon в выводе stty -a ? Это подтягивает его. Вот как POSIX описывает терминал, который должен учитывать символ EOF:

  • EOF
    • Специальный символ ввода, который распознается, если установлен флаг ICANON . При получении все байты, ожидающие чтения, немедленно передаются процессу, не дожидаясь новой строки, а EOF отбрасывается. Таким образом, если нет ожидающих байтов (то есть EOF произошло в начале строки) , нулевое количество байтов должно быть возвращено из чтения ( ) , представляющий индикатор конца файла. Если установлен ICANON , символ EOF будет отброшен при обработке.

Но вы работаете не с каноническим терминалом - вы работаете с терминалом, который будет отправлять любые / все данные любому считывателю, если его спросят, если есть хотя бы один байт для отправки. Терминал не буферизует ввод по строкам - и поэтому он не может заменить байт EOF пустым чтением - вместо этого он просто отправляет байт, который cat только поощряет его продолжать чтение.

  • Если установлен ЗНАЧОК , каноническая обработка должна быть включена.Это включает функции редактирования erase и kill , а также сборку вводимых символов в строки, разделенные NL , EOF и ] EOL , как описано в Обработка входных данных в каноническом режиме .

  • Если ICANON не установлен, запросы на чтение должны удовлетворяться непосредственно из входной очереди. Чтение не должно выполняться до тех пор, пока не будет получено не менее MIN байтов или пока не истечет значение тайм-аута TIME между байтами. Значение времени представляет десятые доли секунды. См. Обработка ввода неканонического режима для получения дополнительной информации.

1
27.01.2020, 22:12

Символ EOT не помечает конец файла. Файл может содержать произвольные байты.

Нажатие Ctrl+D на терминале заставляет приложение думать, что конец файла наступил. Приложение не считывает символ Ctrl+D (EOT), оно видит индикацию конца файла. Интерпретация Ctrl+D как символа конца файла выполняется драйвером терминала в ядре; его можно настроить с помощью команды stty (например, stty eof ^E для изменения символа или stty eof ^- для отключения функции). Это специфично для терминалов, это не относится к обычным файлам, трубопроводам, устройствам, которые не являются терминалами и т.д. В частности, это не относится к последовательным портам.

Нет стандартной утилиты-оболочки, которая останавливает чтение на EOT или на конфигурируемом символе и принимает произвольный двоичный вход. Если на входе нет нулевых байтов, можно использовать команду head или встроенную оболочку read для считывания одной строки после замены EOT на EOL:

data=$(tr '\004\012' '\012\004` | head -n 1 | tr '\004\012' '\012\004`; echo a)
data=${data#a}

(Дополнительная a предназначена для обеспечения сохранения новых строк в конце данных)

.
1
27.01.2020, 22:12

Теги

Похожие вопросы