gpt4 book ai didi

linux - 在 bash 中如何为我正在后台处理的任意程序解析和/或重定向标准输出

转载 作者:太空宇宙 更新时间:2023-11-04 12:42:26 25 4
gpt4 key购买 nike

在之前的question我问如何写入程序的标准输入。这个问题建立在那个问题之上。现在我问“我如何解析我调用的程序的输出”。

在这个例子中我正在调用一个我可以编辑的程序(Sum.sh)这一事实与问题无关。如果我控制我正在调用的程序的实现,我希望这种行为。我想“替换”程序期望的物理人并通过脚本驱动它。

给定两个脚本
总和.sh:

#!/bin/bash 

sum=0
inp=0

while true;
do
printf "Sum: %d\n" $sum
printf "Give me an integer: "
read inp
if [ "$inp" == 0 ]; then
exit
fi
sum=$((sum+inp))
done

和driver.sh:

#!/bin/bash 
rm -f /tmp/sumpipe
mkfifo /tmp/sumpipe

./Sum.sh < /tmp/sumpipe &


echo 2 > /tmp/sumpipe
echo 5 > /tmp/sumpipe
echo 0 > /tmp/sumpipe

sleep 1 # this is required for some reason or the script hangs

然后我运行 driver.sh 我得到以下信息:

$ ./driver.sh 
Sum: 0
Give me an integer: Sum: 2
Give me an integer: Sum: 7
Give me an integer: $

终端输出的格式对于这个问题并不重要。

我想做的是解析所述输出以便在 driver.sh 中做出决定。在以下 driver.sh 的伪代码中,我尝试展示我想要做的事情:

#!/bin/bash 
rm -f /tmp/sumpipe
mkfifo /tmp/sumpipe

output=$(./Sum.sh < /tmp/sumpipe &)

while true; do
if [ "$output" != empty ]; then
(make some decision based on what output is and echo back to my process if necessary)
fi
done

不幸的是,$output从来不包含任何东西,我试过很多版本的abusing readpiping在这个应用程序中,他们都没有为我工作。如何重定向我的后台程序的标准输出以便我可以解析它?


我尝试了 OrangesV 提出的解决方案(并尊重 William Pursell 关于输出缓冲区太空的建议),方法如下:

#!/bin/bash 
rm -f /tmp/sumpipe
mkfifo /tmp/sumpipe

while read output; do
echo "2347823" > /tmp/sumpipe
if [ -z $output ]; then
continue
else
echo "got it!"
echo $output
sleep 1
fi
done < <(./Sum.sh < /tmp/sumpipe &)

不幸的是,“明白了!”从来没有回应过,所以它似乎没有用。

如果相关,我的 bash 版本:

$ bash --version
GNU bash, version 4.4.0(7)-rc2 (x86_64-unknown-linux-gnu)

现在有一个部分解决方案。 Diego Torres Milano 的回答 确实有效。但是,我的 stdio 正在缓冲,因此在 stdio 中至少有 4096 个字节之前我不会得到任何东西。我可以使用以下版本的 driver.sh 强制输出:

#!/bin/bash 

inpipe=/tmp/sumpipei
outpipe=/tmp/sumpipeo

rm -f $inpipe
rm -f $outpipe

mkfifo $inpipe
mkfifo $outpipe

./Sum.sh < $inpipe > $outpipe &


count=0
while true;
do
while read line
do
echo "line=$line"
done < $outpipe &
echo 2 > $inpipe
done

我尝试了各种 stdbuf 的调用(例如:stdbuf -o0 ./Sum.sh <$inpipe > $outpipe &)。 stdbuf在这种情况下显然无法强制关闭缓冲,因为根据 stdbuf 上的 GNU coreutils 手册对于 commandstdbuf option… command :

command must start with the name of a program that does ... not adjust the buffering of its standard streams (note the program tee is not in this category).

不幸的是,这正是我在这里所做的

我将 Diego 的回答标记为正确,即使它在 stdio 缓冲区问题得到解决之前不起作用。我将提出下一个问题来解决 stdio 缓冲问题。我几乎可以在这里尝到奖品的滋味。

最佳答案

使用另一个管道输出

mkfifo /tmp/output
./Sum.sh < /tmp/sumpipe > /tmp/output &

你可以处理它

while read line
do
echo "line=$line"
done < /tmp/output &

关于linux - 在 bash 中如何为我正在后台处理的任意程序解析和/或重定向标准输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39757914/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com