Предоставление ввода для нескольких вызовов read (stdin )через перенаправление ввода bash

В соответствии с подсказкой LL3 выше один из вариантов:

sudo iptables -A POSTROUTING -s 192.168.42.0/24 ! -d 192.168.42.0/24 -j MASQUERADE

и еще один, который неявно ссылается на таблицу nat, которую я использовал, это

sudo iptables --table nat -A POSTROUTING -s 192.168.42.0/24 ! -d 192.168.42.0/24 -j MASQUERADE
0
21.05.2021, 22:22
1 ответ

Скорее всего, это не даст вам приемлемого решения,но учитывая, что:

  • the source code cannot be changed

  • оболочка не может ни изменить место, на которое указывают дескрипторы открытых файлов работающей программы, ни заставить работающую программу прекратить чтение файлового дескриптора

Некоторые альтернативы, которые у вас остаются (за исключением использования состояния гонки ),:

  • Попытка убедиться, что ваша программа всегда получает SIZEбайт за раз:

    {
      echo foo | dd bs=256 conv=sync
      echo bar | dd bs=256 conv=sync
    } 2>/dev/null |./main_read
    

    Выход:

    Enter first input: 
    Enter second input: 
    
    First input:
    foo
    
    Second input:
    bar
    

    Это предполагает, как минимум, что SIZEменьше размера конвейерного буфера.

  • Обертывание вызова вашей программы вexpect(или эквивалентный )скрипт:

    expect <<'EOT'
    spawn./main_read
    expect "Enter first input:"
    send "foo\n"
    expect "Enter second input:"
    send "bar\n"
    expect eof
    EOT
    

    Или, таким образом, чтобы вы могли направлять в него вывод других команд, читайте отдельно (, предполагая, что ваша операционная система предоставляет процессы с файловыми дескрипторами /dev/fd/n):

    echo foo | {
      echo bar |
        expect 4<&0 <<'EOT'
        spawn./main_read
        set chan [open "/dev/fd/3"]
        gets $chan line
        expect "Enter first input:"
        send "$line\r"
        close $chan
        set chan [open "/dev/fd/4"]
        gets $chan line
        expect "Enter second input:"
        send "$line\r"
        close $chan
        expect eof
    EOT
    } 3<&0
    

    В обоих случаях вывод:

    spawn./main_read
    Enter first input: 
    foo
    Enter second input: 
    bar
    
    First input:
    foo
    
    Second input:
    bar
    
  • В системах (, таких как Linux ), которые позволяют открывать каналы неблокирующим -образом, вы можете использовать FIFO, чтобы оболочка читала и записывала в вашу программу. Например:

    makefifo fifo
    {
      exec 3<>fifo
     ./main_read 0<&3
    } |
    sh -c '
      # read a line from the pipe
      # read from a file or a different pipe, write to fifo
      # repeat...
      # echo the output from the pipe
    ' mysh
    

    Хотя, если expectдоступен для вас, я не вижу веских причин для того, чтобы изобретать его заново.

Заметьте, однако, что, как отмечали другие, нет никакой гарантии, что все ваши readпрограммы действительно получат SIZEбайт.

3
28.07.2021, 11:30

Теги

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