私のソリューションを使用していたFIFOと各COMからのメッセージとステータスを取得するためのbash "coproc"組み込み関数パイプのマン。私は前にFIFOを使ったことはなかった。 (オハイオ州の少年、次回はFedoraでBashEclipseを使用しています)。パイプコマンドを管理するための一般的なメカニズムに変わりました。私はこの問題を解決しましたが、10行または20行のコードでは解決しませんでした。 の頑強なドロップイン再利用可能なソリューションの場合は200に似ています(そうするには3日間かかりました)。
私は自分のノートを共有する:
* stderr for all pipe commands goes to the fifos.
If you want to get messages from stdout, you must redirect '1>&2', like this:
PIPE_ARRAY=("cat ${IMG}.md5" "cut -f1 -d\" \" 1>&2")
You must put "2>/fifo" first. Otherwise it won\'t work. example:
cat ${IMG}.md5 | cut -f1 -d' ' 1>&2
becomes:
cat ${IMG}.md5 2>/tmp/fifo_s0 | cut -f1 -d" " 2>/tmp/fifo_s1 1>&2 ; PSA=("${PIPESTATUS[@]}")
* With more tha one fifo, I found that you must read each fifo in turn.
When "fifo1" gets written to, "fifo0" reads are blocked until you read "fifo1"
I did\'nt use any special tricks like "sleep", "cat", or extra file descriptors
to keep the fifos open.
* PIPESTATUS[@] must be copied to an array immediately after the pipe command returns.
_Any_ reads of PIPESTATUS[@] will erase the contents. Super volatile !
"manage_pipe()" appends '; PSA=("${PIPESTATUS[@]}")' to the pipe command string
for this reason. "$?" is the same as the last element of "${PIPESTATUS[@]}",
and reading it seems to destroy "${PIPESTATUS[@]}", but it's not absolutly verifed.
run_pipe_cmd() {
declare -a PIPE_ARRAY MSGS
PIPE_ARRAY=("dd if=${gDEVICE} bs=512 count=63" "md5sum -b >${gBASENAME}.md5")
manage_pipe PIPE_ARRAY[@] "MSGS" # (pass MSGS name, not the array)
}
manage_pipe() {
# input - $1 pipe cmds array, $2 msg retvar name
# output - fifo msg retvar
# create fifos, fifo name array, build cnd string from $1 (re-order redirection if needed)
# run coprocess 'coproc execute_pipe FIFO[@] "$CMDSTR"'
# call 'read_fifos FIFO[@] "M" "S"' (pass names, not arrays for $2 and $3)
# calc last_error, call _error, _errorf
# set msg retvar values (eval ${2}[${i}]='"${Msg[${i}]}"')
}
read_fifos() {
# input - $1 fifo array, $2 msg retvar name, $3 status retvar name
# output - msg, status retvars
# init local fifo_name, pipe_cmd_status, msg arrays
# do read loop until all 'quit' msgs are received
# set msg, status retvar values (i.e. eval ${3}[${i}]='"${Status[${i}]}"'
}
execute_pipe() {
# $1 fifo array, $2 cmdstr, $3 msg retvar, $4 status retvar
# init local fifo_name, pipe_cmd_status arrays
# execute command string, get pipestaus (eval "$_CMDSTR" 1>&2)
# set fifo statuses from copy of PIPESTATUS
# write 'status', 'quit' msgs to fifo
}
ありがとうございます。私は 'pipefail'について知りませんでした。 – jerry
これはshでも有効です。ありがとうございました。 – AnkurTank