bash中的IPC(使用命名管道,而不是使用expect)

bash中的IPC(使用命名管道,而不是使用expect),bash,ipc,named-pipes,Bash,Ipc,Named Pipes,我正在编写一个bash脚本,它应该与现有的(perl)程序交互。不幸的是,我不能接触现有的perl程序,也不能使用它 目前,该脚本的工作方式与此stackoverflow答案相同 问题是(阅读:似乎是)perl程序在请求输入之前并不总是发送。这意味着bash的在。。。指定管道上的read不会“获取”(read:display)perl程序的输出,因为它一直在等待更多的输出。至少我是这样理解的 因此,基本上perl程序正在等待输入,但用户不知道,因为屏幕上没有任何内容 所以我在bash脚本中所做的

我正在编写一个bash脚本,它应该与现有的(perl)程序交互。不幸的是,我不能接触现有的perl程序,也不能使用它

目前,该脚本的工作方式与此stackoverflow答案相同

问题是(阅读:似乎是)perl程序在请求输入之前并不总是发送
。这意味着bash的
在。。。指定管道上的read
不会“获取”(read:display)perl程序的输出,因为它一直在等待更多的输出。至少我是这样理解的

因此,基本上perl程序正在等待输入,但用户不知道,因为屏幕上没有任何内容

所以我在bash脚本中所做的是关于

#!/bin/bash

mkfifo $readpipe
mkfifo $writepipe

[call perl program] < $writepipe &> $readpipe &
exec {FDW}>$writepipe
exec {FDR}<$readpipe

...

while IFS= read -r L
do
    echo "$L"
done < $readpipe
但不是

    ? [C]
这不是问题最多的案例,而是最容易描述的案例


有没有办法确保
?[C] 
也是打印的(我玩了
catUse
read-N1

让我们尝试以下示例:与发送提示符的程序交互(不是以换行符结束),我们的系统必须发送一些命令,接收发送的命令的回音。也就是说,子进程的总输出为:

$ cat example 
prompt> command1
prompt> command2
脚本可以是:

#!/bin/bash 
#

cat example | while IFS=$'\0' read -N1 c; do
  case "$c" in
  ">") 
       echo "received prompt: $buf" 
        # here, sent some command
       buf=""
       ;;
  *)
      if [ "$c" == $'\n' ]; then
        echo "received command: $buf"
        # here, process the command echo
        buf=""
      else
        buf="$buf$c"
      fi
      ;;
  esac
done
这将产生以下输出:

received prompt: prompt
received command:  command1
received prompt: prompt
received command:  command2
第二个例子更接近原始问题:

$cat示例

Choose action:
[A]: Action A      [B]: Action B
[C]: cancel
    ? [C]
脚本现在是:

#!/bin/bash 
#

while IFS=$'\0' read -N1 c; do
  case "$c" in
  '?') 
       echo "*** received prompt after: $buf$c ***" 
       echo '*** send C as option ***'
       buf=""
       ;;
  *)
      buf="$buf$c"
      ;;
  esac
done < example

echo "*** final buffer is: $buf ***"

尝试在
[C]
之后添加一个换行符,即打印
“[C]\n”
这可能是您的coproc方法可行的,但由于我手头没有答案,我可以看到一个特别难看的解决方法,即在您知道的缺少的换行符之后插入换行符(即:
$readpipe&
您可以使用python吗?如果可以,用一个python包装器来替换
[call perl program]
,该包装器在其周围提供伪终端?
/usr/bin/env python-c“import pty,sys;pty.spawn(sys.argv[1:])”/path/to/program.pl<$writepe&>$readpipe
您认为是空的吗?在我看来,这看起来像是Perl脚本中的缓冲问题。尝试将
$++
放在Perl脚本的顶部。我知道这很旧,但如果这是您看到的问题的解决方案,那将很有趣。我明白了(并且喜欢)我相信是你的基本想法。不幸的是,它在我的情况下不起作用。我还不知道为什么。我的脚本似乎出于某种原因从未读过“?”(或者从未看到“\0”)。@scherand:你能编辑原始问题,添加新的脚本版本及其输出吗?可能很有趣,添加一个回音“$c”:作为while循环中的第一条语句,查看处理了哪些字符。
Choose action:
[A]: Action A      [B]: Action B
[C]: cancel
    ? [C]
#!/bin/bash 
#

while IFS=$'\0' read -N1 c; do
  case "$c" in
  '?') 
       echo "*** received prompt after: $buf$c ***" 
       echo '*** send C as option ***'
       buf=""
       ;;
  *)
      buf="$buf$c"
      ;;
  esac
done < example

echo "*** final buffer is: $buf ***"
*** received prompt after: 
Choose action:[A]: Action A      [B]: Action B
[C]: cancel
    ? ***
*** send C as option ***
*** final buffer is:  [C]
 ***