Как вызвать программу и передать ей стандартный ввод

Как вызвать программу и передать ей стандартный ввод? Гипотетический пример в Bash:

(echo abc; echo abba) | tr b B

Заметить что:

  • У меня нет входных данных в строке (я генерирую их по мере итерации)
  • Я не знаю, как долго вход
  • Входные данные могут занимать несколько строк, как в этом примере

Я уже написал это на 19 других языках, обычно я подхожу к этому, чтобы получить файловый дескриптор для стандартного ввода программы, а затем записать в файловый дескриптор таким же образом, как я бы написал в стандартный вывод.

Что я пробовал до сих пор: на основе вызова внешней программы и передать аргументы я пытался передать его эхо и с помощью оболочки для обработки трубопровода. Это не работает, если мои входные данные содержат одинарные кавычки, и это не работает, если у меня нет моих входных данных в строке (которых у меня нет)

Вот мой код, в настоящее время пытается вытащить его, вычисляя строку, которая будет напечатана (это не удается прямо сейчас).

2 ответа

  1. Что касается одинарной кавычки, как насчет вставки escape-символа ( \) перед каждой кавычкой ( ')…? Кажется, это работает как-то для» минимального » примера:

    module utils
        implicit none
    contains
    
    function esc( inp ) result( ret )
        character(*), intent(in) :: inp
        character(:), allocatable :: ret
        integer :: i
    
        ret = ""
        do i = 1, len_trim( inp )
            if ( inp( i:i ) == "'" ) then
                ret = ret // "\'"
            else
                ret = ret // inp( i:i )
            endif
        enddo
    endfunction
    
    endmodule
    
    program test
        use utils
        implicit none
        character(100) :: str1, str2
        integer i
    
        call getcwd( str1 )   !! to test a directory name containing single quotes
        str2 = "ab'ba"
    
        print *, "trim(str1) = ", trim( str1 )
        print *, "trim(str2) = ", trim( str2 )
        print *
        print *, "esc(str1) = ", esc( str1 )
        print *, "esc(str2) = ", esc( str2 )
    
        print *
        print *, "using raw str1:"
        call system( "echo " // trim(str1) // " | tr b B" )
    
        print *
        print *, "using raw str2:"
        call system( "echo " // trim(str2) // " | tr b B" )  !! error
    
        print *
        print *, "using esc( str1 ):"
        call system( "echo " // esc(str1)  // " | tr b B" )
    
        print *
        print *, "using esc( str2 ):"
        call system( "echo " // esc(str2)  // " | tr b B" )
    
        print *
        print *, "using esc( str1 ) and esc( str2 ):"
        call system( "(echo " // esc(str1) // "; echo " // esc(str2) // ") | tr b B" )
    
        ! pbcopy (copy to pasteboard; mac-only)
        ! call system( "(echo " // esc(str1) // "; echo " // esc(str2) // ") | pbcopy" )
    
    endprogram
    

    Если мы запустим вышеуказанную программу в каталоге/foo/baa/x\'b\'z, мы получим

     trim(str1) = /foo/baa/x'b'y
     trim(str2) = ab'ba
    
     esc(str1) = /foo/baa/x\'b\'y
     esc(str2) = ab\'ba
    
     using raw str1:
    /foo/baa/xBy
    
     using raw str2:
    sh: -c: line 0: unexpected EOF while looking for matching `''
    sh: -c: line 1: syntax error: unexpected end of file
    
     using esc( str1 ):
    /foo/baa/x'B'y
    
     using esc( str2 ):
    aB'Ba
    
     using esc( str1 ) and esc( str2 ):
    /foo/baa/x'B'y
    aB'Ba
    
  2. Это то, что я имею в виду под минимальным примером.

     call execute_command_line("(echo ""hexxo world"";echo abba)|tr x l")
     end
    
     Привет мир
     авва

    Разве это не делает именно то, что вы просите, вызывая trи передавая стандартный ввод?