여러 백그라운드 기능에서 bash 읽기 명령의 프로세스 간 통신

여러 백그라운드 기능에서 bash 읽기 명령의 프로세스 간 통신

다음 코드를 기본 입력에서 읽고 함수에서 읽은 다음 다른 함수의 입력으로 보낼 수 있도록 노력하고 있지만 작동하도록 할 수 없고 입력해야 합니다. 구문 분석할 수 있도록 명령을 가져옵니다.

coproc test {
for i in $(seq 0 9)
    do
        sleep 1
        echo $i
done
}
input() { while read -u 3 gr
    do
        echo sent: $gr # this should send to output function
done
}
output() { while read idk
    do
        echo received: $idk | sed s/r/R/ | sed 's/5/five/' # this should receive from input function
done
}
exec 3>&${test[0]}
exec 4>&${test[1]}
input <&3 &>4 & # remove >&4 to see output
export input_PID=$!
output <&4 &
sleep 11
exec 3>&- 4>&-
echo finished

fd를 사용하여 다양한 리디렉션을 시도했지만 아무것도 작동하지 않는 것 같습니다. 도와주세요. 사용자가 각 함수에 대한 코드를 복제하지 않고 (출력 함수가 읽은 내용에 따라) 입력 함수에 명령을 보낼 수 있다는 아이디어입니다. 그 반대로(입력 함수는 출력 함수로 보낼 수도 있음), fd3 또는 fd4로 보내는 것은 읽기 자체를 우회하고 최종 출력을 수신하는 명령으로 직접 보내는 것처럼 작동하지 않습니다.

이는 최소한의 예일 뿐이며 전체 사용법은 다음과 같습니다.

스크립트의 기본 프로세스 레이아웃(각 들여쓰기는 소스 깊이 또는 하위 프로세스 깊이를 나타냄):

Code_Bash
    . ./modules/module_controller
        . ./modules/module_trap
            . ./modules/module_finish
        until [[ $FIN == 1 ]] ; do
        . ./modules/module_loader
            . ./modules/module_colors
            . ./modules/module_tracker
            . ./modules/module_config
            . ./modules/module_kill_all_panes
            . ./modules/module_irc_session
                . ./modules/module_input
            . ./modules/module_irc_read
                . ./modules/module_output
                . ./modules/module_handler
                . ./modules/module_user_input
            . ./modules/module_array
            if [[ -z $IRC_NC_PID && $IRC_FIN == "0" ]] ; then
            . ./modules/module_coproc_nc
            . ./modules/module_rest_of_script
            fi
            . ./modules/module_null
        done

https://github.com/mgood7123/UPM/blob/master/Files/Code/modules/module_loader(이것은 지속적으로 수행됩니다)

https://github.com/mgood7123/UPM/blob/master/Files/Code/modules/module_coproc_nc

https://github.com/mgood7123/UPM/blob/master/Files/Code/modules/module_irc_read(핵심 모듈은 별도의 백그라운드 프로세스에서 실행됨)

https://github.com/mgood7123/UPM/blob/master/Files/Code/modules/module_irc_session(핵심 모듈은 별도의 백그라운드 프로세스에서 실행됨)

https://github.com/mgood7123/UPM/blob/master/Files/Code/modules/module_rest_of_script(이것은 IRC_READ 및 IRC_SESSION의 백그라운드 기능을 실행합니다.)

답변1

문제는 입력과 출력을 혼동하고 있다는 것입니다.

exec 3>&${test[0]}
exec 4>&${test[1]}
input <&3 &>4 &

둘 다 열어서 글쓰기에만 사용합니다 &3. &4하지만 첫 번째 것은 읽을 수만 있습니다. &3쓰기용으로만 fd를 열었기 때문에 읽기가 실패했습니다. 당신에게 필요한 것은

exec 3<&${test[0]}

답변2

첫째, 스크립트에서 작동하지 않는 것:

exec 3>&${test[0]}

coproc 출력은 ${test[0]}쓰기가 아닌 읽기를 위한 파일 설명자입니다. 당신이 의미한다고 가정3<&${test[0]}

input <&3 &>4 &

첫째, &>4"stdout 및 stderr을 4라는 파일로 리디렉션"을 의미합니다 >&4. 이제 FD #4는 coproc에 대한 입력이므로 test(테스트에서는 이를 읽지 않음) 리디렉션은 거의 의미가 없습니다.

output <&4 &

오타가 없으면 FD #4는 읽을 수 없는 출력 파일 설명자(coproc의 표준 입력에 바인딩됨)가 됩니다.


이제 나는 당신이 원한다고 가정하고 작동 코드를 제공하려고 노력할 것입니다:

  • 백그라운드 프로세스는 inputFD #3의 모든 내용을 읽고 전송하며 output각 줄 앞에는 "sent"라는 접두사가 붙습니다.
  • 또 다른 백그라운드 프로세스는 전송된 내용을 output읽고 input앞에 "received"를 추가하고 일부 문자열 처리를 수행한 후 결과를 표준 출력에 기록합니다.

일반적으로 이는 다음과 같이 간단합니다.

test() for i in {0..9}; do sleep 1; echo $i; done    # No coproc

input() while read gr; do echo sent: $gr; done       # Reads from stdin, not FD #3

# output() unmodified

exec 3> >(input | output)
test >&3

input하지만 내 생각에는 어떤 이유로든 별도로 생성하여 백그라운드 에 두고 싶어한다는 것입니다 . 그런 다음 다음을 시도하십시오.outputtest

exec 4> >(output)
output_PID=$!

exec 3> >(input >&4)
input_PID=$!
exec 4>&-

test >&3 &
wait

관련 정보