複数のバックグラウンド機能における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

関連情報