我已经给了一些编译的程序。 我想通过程序stdin和stdout从我的bash脚本与它进行通信。 我需要双向沟通。 程序不能在交换信息之间死亡。 我怎么能做到这一点? 简单的例子:
让该程序被编译部分总结(C ++)和脚本结果将是该和的平方。 程序:
int main() { int num, sum = 0; while(true) { std::cin >> num; sum += num; std::cout << sum << std::endl; } }
我的脚本应该是这样的:
for i in 1 2 3 4; do echo "$i" > program read program to line; echo $((line * line)) done
如果在程序中我有for(int i = 1; i <= 4; ++i)
,那么我可以这样做:
exec 4< <(./program); # Just read from program for i in 1 2 3 4; do read <&4 line; echo "sh: $((line * line))"; done
为更多看这里 。 另一方面,如果在程序中我有std::cout << sum * sum;
,那么解决scheme可能是:
exec &3> >(./program); # Write to program for i in 1 2 3 4; do echo "$i" > &3 done
我的问题是与其他进程/程序的双向沟通。 我不必使用exec。 我无法安装第三方软件。 只有Bash的解决scheme,没有文件,将是很好的。
如果我运行其他进程,那么知道在脚本结束时将pid杀死是很好的。
我想在未来与两个或三个进程的沟通。 第一节目的输出可能依赖于第二节目的输出,也可能在第二节节目的输出。 像过程的沟通者。
但是,我不能重新编译程序并改变一些东西。 我在程序中只有stdin和stdout通信。
如果你有比4.0更新的bash,你可以使用coproc 。
但是,请不要忘记,要传输的命令的输入/输出可能会被缓冲。
在这种情况下,你应该用stdbuf -i0 -o0
来包装命令
参考: 如何使输出的任何shell命令无缓冲?
这是一个例子
#!/bin/bash coproc mycoproc { ./a.out # your C++ code } # input to "std::cin >> num;" echo "1" >&${mycoproc[1]} # get output from "std::cout << sum << std::endl;" # "-t 3" means that it waits for 3 seconds read -t 3 -u ${mycoproc[0]} var # print it echo $var echo "2" >&${mycoproc[1]} read -t 3 -u ${mycoproc[0]} var echo $var echo "3" >&${mycoproc[1]} read -t 3 -u ${mycoproc[0]} var echo $var # you can get PID kill $mycoproc_PID
输出将是
1 3 6
如果你的bash比4.0大,使用mkfifo
可以做同样的事情,比如:
#!/bin/bash mkfifo f1 f2 exec 4<> f1 exec 5<> f2 ./a.out < f1 > f2 & echo "1" >&4 read -t 3 -u 5 var echo $var rm f1 f2
考虑到你的C ++程序从标准输出读取,并打印到标准输出,很容易把它放在一个简单的管道链中:
command_that_writes_output | your_cpp_program | command_that_handle_output
在你的具体情况下,你可能需要修改程序只处理一个单一的输入,并写一个单一的输出,并删除循环。 因为那么你可以做得很简单,就像这样:
for i in 1 2 3 4; do result=`echo $i | ./program` echo $((result * result)) done