次のコードを基本入力から読み込み、関数から読み取ってから、他の関数の入力に送信するように努力していますが、動作させることはできず、入力する必要があります。解析できるようにコマンドを取得します。
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の標準入力にバインドされています)になります。
今私はあなたが欲しいと仮定し、動作コードを提供しようとします:
- バックグラウンドプロセスは
input
FD#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
しかし、私の考えでは、何らかの理由で別々に生成してバックグラウンドに置きたいということです。次に、次のことを試してください。output
test
exec 4> >(output)
output_PID=$!
exec 3> >(input >&4)
input_PID=$!
exec 4>&-
test >&3 &
wait