【问题标题】:bash/sh/busybox pass stdin to child processbash/sh/busybox 将标准输入传递给子进程
【发布时间】:2016-07-29 23:24:32
【问题描述】:

我想通过标准输入将脚本和数据通过管道传输到 shell 及其子进程。基本上,我正在启动一个 shell 并通过标准输入向 shell 发送一个类似 "exec wc -c;\n<data>" 的字符串。

我希望启动一个子流程并将数据传递给所述子流程。 使用 exec 我完全希望 wc -c 替换我的 shell 并计算通过标准输入发送的字节数。

例子:

echo -ne 'exec wc -c;\nabc' | dash
echo -ne 'exec wc -c;\nabc' | bash
echo -ne 'exec wc -c;\nabc' | bash --posix
echo -ne 'exec wc -c;\nabc' | busybox sh

它似乎与 bash 一致,但不适用于 dash 或 busybox sh。他们似乎都间歇性地失败了。如果我在通过标准输入发送<data> 之前睡了 100 毫秒,那么它可以工作。但是睡觉并不是一个可靠的解决办法。

实际上,我正在发送大量数据,因此我不想对其进行编码或以某种方式将其存储在内存中。有什么想法吗?

注意:我确信有很多用例可以解决这个问题。但我正在寻找为什么这不能始终如一地工作。和/或我可以做些什么来让它可靠地工作,最好是跨平台:)

更新:为了澄清我有一个远程系统,我在其中运行 sh 并公开 stdin/stdout/stderr,我想证明这样的设置可以做任何事情。通过发送"exec cat - > /myfile;\n<data>",可以想象我可以流入/myfile,这样它就包含<data>。再次想象<data> 很大。

本质上,我希望证明可以仅使用sh 的标准输入来控制系统。除了sh 之外,其他非常简单的东西也可以作为静态二进制文件跨平台使用。

我承认这可能完全是疯狂的,我应该使用像 SSH 之类的协议,但我可能不得不实现它。

【问题讨论】:

  • 为什么要启动一个shell?为什么不echo -n 'abc' | wc -c 或更一般地说generatedata | process?你认为启动一个 shell 然后exec-ing 出来的好处是什么?
  • 顺便说一句,如果您关心可移植性,您可能希望养成使用带有 any 标志的printf 而不是echo 的习惯; -n 在 POSIX 中是明确的未定义行为,而任何 echo 在其参数列表中传递 -e 时,除了在输出上打印 -e 之外执行任何其他操作,不仅在未定义空间中,而且行为与标准相反。请参阅pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html,尤其包括应用使用部分。

标签: bash shell sh busybox


【解决方案1】:

这对我来说似乎适用于 bash,但对于 dash 或 busybox sh 则完全不适用。我很惊讶它根本起作用。我希望 shell 在处理任何内容之前从其标准输入读取大量输入,包括第一行的命令和之后的数据。这不会在执行命令的标准输入上留下任何东西。

在实践中,bash 似乎一次读取 1 个字节,直到它看到换行符,然后立即执行,所以一切都很好。

dash 和 busybox sh 完全符合我的预期,首先读取整个输入。

可以吗

echo -ne "exec wc -c <<'END'\nabc" | sh

相反?如果您担心它会出现在输入中,可以将 END 替换为 END_adjfioe38999f3jf_END?

更新:尽管仔细想想,这不符合您的“不在内存中缓冲”标准。呃……好吧,这很难。如果你能保证命令运行在 4k 以内,那么像这样可怕的东西会“起作用”:

echo -ne "exec wc -c\nabc" | perl -e 'sysread(STDIN, $buf, 4096); $buf =~ s/([^\n]*)\n//; open(my $pipe, "|-", $1); syswrite($pipe, $buf); open(STDOUT, ">&", $pipe); exec("cat")'

但这并不是您正在寻找的便携式基于 shell 的解决方案。 (它读取一个 4k 的输入块,从中获取命令,分叉并生成一个运行该命令的 shell,通过管道连接,将剩余的初始块发送到管道,将自己的标准输出复制到管道,然后execs cat 一次将其标准输入复制到管道,管道将在其标准输入上接收它。我认为这就是您最终想要发生的事情,只需使用更简单的基于 shell 的语法。

【讨论】:

  • 嘿嘿,这是一个有趣的问题..@sfink 用例正在通过将cat - 发送到sh 来测试taskcluster 交互式shell,这是shell 运行的......理想情况下,如果我可以让它可靠地工作,我们还可以使用 shell 传输文件和其他疯狂的东西......但我怀疑我最终可能不得不运行 bash 而不是更容易嵌入的 sh/busybox。
猜你喜欢
  • 2015-12-12
  • 2020-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-07
  • 2021-11-03
  • 2020-09-05
  • 2014-02-13
相关资源
最近更新 更多