Ввод-вывод через поток - Longchar Input - PullRequest
0 голосов
/ 21 января 2019

будет полезна помощь со следующим.

Я пытаюсь запустить текущую ОС-команду, используя ввод-вывод через.

Корпус:

Run command: "echo 'this is a long string'"
Capture output: "'this is a long string'"

Проблемы:

  • Моя строка ввода может быть больше, чем ограничение на число символов
  • При непосредственном запуске с использованием through "program" или through value("expression") Вход усечен до ~ 2500-3000 символов.
  • Вся операция выполняется нормально с использованием файлов, но нужно избегать ввода-вывода и управления.
  • Возникли проблемы с подключением моих данных к команде ОС (используется put ИЛИ export)

Может ли кто-нибудь предложить метод для выполнения командной строки, в котором присоединенные данные превышают 35 000 символов?

Вот что я пробовал: (Наряду со многими перестановками)

define variable cLongMsg as character  no-undo.
define variable iLoop as integer no-undo.
define variable lcResp as longchar no-undo.
define variable cFileLine as character no-undo.    
define stream logStream.

input-output stream logStream through "curl".
  /* execute curl -- attach data using put */
  put stream logStream "http://stackoverflow.com".
  put stream logStream "-d 'key=long_data"
  put stream logStream "&value=more_long_data'"
  put stream logStream CONTROL NULL(0).
output close.     

read_loop:
repeat:

    import stream logStream unformatted cFileLine.
    assign lcResp = lcResp + cFileLine.
end.

input close.
input-output close.

message "[OUT] " + string(lcResp) view-as alert-box.

Используемое в настоящее время решение:

Файл прогресса

function CURL_long returns longchar private (
         input cInput as longchar).

  def var cUnixCMD                      as longchar                     no-undo.
  def var cDataPart                     as char                         no-undo.
  def var cData                         as longchar                     no-undo.    
  def var cResultChunk                  as char                         no-undo.
  def var iResultChunkMax               as inte      init 30000         no-undo.
  def var iUsedChunkMax                 as inte                         no-undo.
  def var iResultPos                    as inte                         no-undo.

  fix-codepage(cData) = "UTF-8".

  assign cUnixCMD = "curl " + cInput + " | fold -c30000".

  input-output stream CURL_CMD through "input_buffer.sh".

  /* set the result position */
  assign iResultPos = 0.

  ResultLoop:
  repeat:
    if iResultPos + iUsedChunkMax > length(cUnixCMD) then
    do:
      assign cResultChunk = substring(cUnixCMD, iResultPos + 1).
      put stream CURL_CMD unformatted cResultChunk skip.
      leave ResultLoop.
    end.

    /* set the current chunk of the result */
    assign cResultChunk = substring(cUnixCMD, iResultPos + 1, iResultChunkMax)
           iUsedChunkMax = iResultChunkMax.

    put stream CURL_CMD unformatted cResultChunk skip.

    assign iResultPos = iResultPos + iUsedChunkMax.

  end. /* ResultLoop: repeat: */
  output stream CURL_CMD close.

  read_loop:
  repeat:
    import stream CURL_CMD unformatted cDataPart.
    if cDataPart <> "" then assign cData = cData + cDataPart.
    else leave.
  end.

  return cData.

end function.

Файл Bash

#!/bin/bash
myCMD=""
while IFS= read line
do
  myCMD+=$line
done    
eval $myCMD
exit

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Вы на правильном пути с несколькими небольшими проблемами синтаксиса.

Это работает для меня:

define variable lcResp as longchar no-undo.
define variable cFileLine as character no-undo.

define stream logStream.

input stream logStream through "curl https://stackoverflow.com".

read_loop:
repeat:

  import stream logStream unformatted cFileLine.

  assign lcResp = lcResp + cFileLine + "~n".

end.

input stream logStream close.

message "[OUT] " length( lcResp ) view-as alert-box.

COPY-LOB lcResp to file "zzz".

Оператор MESSAGE не может вывести lcResp, если он превышает примерно 30000 символов. Я использовал length (lcResp), чтобы показать, что я получил данные.

Операторы вывода, такие как MESSAGE, PUT или EXPORT, не работают с данными longchar. Вам нужно использовать COPY-LOB для непосредственного чтения или записи longchar.

Также - будьте осторожны с обработкой новых строк или их отсутствием. ВХОД, который не завершается символом новой строки, будет потерян ИМПОРТОМ в цикле REPEAT. Я обычно использую что-то еще, чтобы избежать этого:

define variable lcResp as longchar no-undo.
define variable cFileLine as character no-undo.

define stream logStream.

input stream logStream through "curl https://stackoverflow.com".

read_loop: do while true:

  cFileLine = ?.

  do on endkey undo, leave
     on error undo, leave:

    import stream logStream unformatted cFileLine.

  end.

  if cFileLine = ? then
    leave read_loop.
   else
    lcResp = lcResp + cFileLine + chr(13) + chr(10).

end.

input stream logStream close.

message "[OUT] " length( lcResp ) view-as alert-box.

COPY-LOB lcResp to file "zzz".

Бизнес "chr (13) + chr (10)" может быть важен, если ваши переводы строк должны иметь определенный формат.

0 голосов
/ 21 января 2019

Вы можете использовать параметр запуска -inp для решения проблемы.Больше информации здесь: https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dpspr/input-characters-(-inp).html

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