如何将 bash shell 连接到命名管道?

如何将 bash shell 连接到命名管道?

假设我有两个共享卷的容器 X 和 Y(实际上是同一个 Kubernetes pod 中的两个容器)。在该卷上有一个命名管道/foo,我希望将其附加到容器 Y 上的 bash 进程。当容器 X 将数据发送到容器 Y 时,我希望它以与例如相同的方式工作ssh:该命令应该由远程 bash 读取外壳、管道等都是透明处理的。

我在机器 Y 上尝试了以下操作:

  • bash -s <> /foo:如果从机器 XI 运行echo “ls -l” > /foo; cat /foo,则该命令在 Y 上运行,但输出进入 Y 的终端而不是命名管道

  • bash -s < /foo > /foo如果从机器 XI 运行echo “ls -l” > /foo; cat /foo,那么什么也不会发生

  • bash -s < /foo | cat - > foo:如果从机器 XI 运行echo “ls -l” > /foo; cat /foo,则命令在 Y 上运行,输出出现在 X 的终端上,然后在 Y 上不再执行任何命令,并且 X 挂起。

我正在寻找的可能是将 X 上的当前 shell 附加到命名管道,并在 X 上将其附加到新 shell 的方法。再次,我希望它像ssh以前一样工作,您可以连接并发送单个非交互式命令(或脚本)和/或管道数据,并且以某种方式它按照您期望的方式工作。我只是还没有找到合适的 shell fu 来实现它。

我也不明白为什么上面的三个选项会产生不同的结果。

答案1

要将 bash shell 附加到命名管道,可以使用该exec命令将当前 shell 进程替换为连接到命名管道的新进程。例如,如何在机器 Y 上执行此操作:

cat /foo | bash

这将用一个读取和写入命名管道的新 shell 进程替换当前的 shell 进程/foo。现在,从机器 X 发送到的任何命令或数据都/foo将被机器 Y 上的新 shell 进程读取。

关于您的三种尝试和不同的结果:

  1. bash -s <> /foo:此命令运行一个新的 shell 进程,该进程从标准输入读取并写入标准输出。该<>语法告诉 shell 打开命名管道以进行读取和写入。当您echo "ls -l" > /foo在机器 X 上运行时,它将字符串“ls -l”写入命名管道,然后由机器 Y 上的新 shell 进程读取该字符串。该命令在 Y 上执行,但输出打印到 Y 的终端被写入命名管道。

  2. bash -s < /foo > /foo:此命令运行一个新的 shell 进程,该进程从命名管道读取数据并向命名管道写入数据。当您echo "ls -l" > /foo在机器 X 上运行时,它会将字符串“ls -l”写入命名管道,然后机器 Y 上的新 shell 进程会读取该字符串。但是,shell 进程也会写入相同的命名管道,这会创建陷入僵局并导致什么也不会发生。

  3. bash -s < /foo | cat - > foo:此命令运行一个新的 shell 进程,该进程从命名管道中读取数据并将其输出传输到 cat 命令,该命令写入常规文件foo。当您echo "ls -l" > /foo在机器 X 上运行时,它将字符串“ls -l”写入命名管道,然后由机器 Y 上的新 shell 进程读取该字符串。该命令在 Y 上执行,输出出现在 X 的终端上,因为它正在写入 X 上运行的 cat 进程。但是,cat 进程不会将任何内容写回到命名管道,这会导致计算机 Y 上的新 shell 进程挂起。

答案2

好的,在 Telometto、Kamil 和 Greg A. Woods 的帮助下,我得到了以下解决方案,这似乎满足了我的需求:

  • 在共享卷上,创建命名管道stdinstdoutstderr
  • 在机器 Y 上运行while true; do bash -s < stdin 2> stderr > stdout ; done
  • 在机器 XI 上创建了一个帮助程序脚本来帮助运行远程命令:
#!/bin/bash

trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM

(
  echo "$@"
  if read -t 0 ; then
    cat - 2> /dev/null
  fi
) | cat > stdin

cat stdout &
cat stderr > /dev/stderr &

wait

要使用它,您只需./run "ls -l"从 X 开始,然后在 Y 上运行命令。您也可以从 X 开始,在 Y 上运行命令,一路将./run "cat > bar" < foo(在本例中)X 的内容移动到 Y。foo管道输入的处理方式类似。

相关内容