Bash 使用流重定向调用后台服务 我有后台服务;该示例显示了一个简单的程序,它将输入回送到stdout和stderr。通常这是一个需要一些时间才能启动的服务器进程 我想单独调用此服务,并能够获取输出–就好像每次调用都启动了此服务一样。两个输出流必须分开处理

Bash 使用流重定向调用后台服务 我有后台服务;该示例显示了一个简单的程序,它将输入回送到stdout和stderr。通常这是一个需要一些时间才能启动的服务器进程 我想单独调用此服务,并能够获取输出–就好像每次调用都启动了此服务一样。两个输出流必须分开处理,bash,io,background-process,Bash,Io,Background Process,例如: #!/bin/bash rm -f a o e mkfifo a o e # Background echo service ( while read l; do sleep .5 >&2 echo "$l;" echo "$l." done ) < a > o 2> e & # Service call call () {

例如:

#!/bin/bash

rm -f a o e
mkfifo a o e

# Background echo service
(
    while read l; do
        sleep .5
        >&2 echo "$l;"
        echo "$l."
    done
) < a > o 2> e &

# Service call
call () {
    
    echo "$1" > a &

    # Reading of stdout+err must run in parallel,
    # else service output to one FIFO would block reading the other

    (
        echo waiting.
        read out < o
        echo ">${#out}$out"
    ) &
    p1=$!

    (
        echo 'waiting;'
        read err < e
        >&2 echo ">${#err}$err"
    ) &
    p2=$!

    wait $p1
    wait $p2
}

a="$(call ABC)"
echo "$a"
call DEF
call GHI
第二个调用被阻塞,没有更多输出。我必须取消剧本

我的猜测是,子shell中的
read out
read err
绑定到FIFO。我不能让FIFO在单独的进程中读取(如服务),因为否则我无法将
call
的输出捕获到变量中

如何捕获单独调用的输出并为每个调用重新绑定o和e FIFO?由于两个流的并行读取,因此必须使用子shell

备选方案:执行相同的操作,但将文件用于stderr:

#!/bin/bash

rm -f a o e
mkfifo a o
> e

# Background echo service
(
    while read l; do
        sleep .5
        >&2 echo "$l;"
        echo "$l."
    done
) < a > o 2> e &

# Service call
call () {
    
    echo "$1" > a &

    declare out=
    echo waiting.
    while [ ! "$out" ]; do
        read out < o
    done
    echo ">${#out}$out"

    declare err=
    echo 'waiting;'
    while [ ! "$err" ]; do
        read err < e
    done
    >&2 echo ">${#err}$err"
}

a="$(call ABC)"
echo "$a"
call DEF
call GHI
#/bin/bash
rm-f a o e
mkfifo
>e
#后台回显服务
(
当我读的时候;做
睡觉
>&2回声“$l
回音“$l”
完成
)o2>e&
#服务电话
调用(){
回声“$1”>a&
宣布=
回声等待。
而[!“$out”];则
读出${out}$out”
宣告错误=
回声“等待”
而[!“$err”];则
读取错误&2 echo“>${#err}$err”
}
a=“$(呼叫ABC)”
回音“$a”
呼叫DEF
打电话给GHI
同样的结果是,读取的第二个
在没有打印任何内容的情况下被阻塞

#!/bin/bash

rm -f a o e
mkfifo a o
> e

# Background echo service
(
    while read l; do
        sleep .5
        >&2 echo "$l;"
        echo "$l."
    done
) < a > o 2> e &

# Service call
call () {
    
    echo "$1" > a &

    declare out=
    echo waiting.
    while [ ! "$out" ]; do
        read out < o
    done
    echo ">${#out}$out"

    declare err=
    echo 'waiting;'
    while [ ! "$err" ]; do
        read err < e
    done
    >&2 echo ">${#err}$err"
}

a="$(call ABC)"
echo "$a"
call DEF
call GHI