bash / sh / busybox将stdin传递给子进程

时间:2016-07-29 23:24:33

标签: bash shell sh busybox

我想通过stdin将脚本和数据都传递给shell及其子进程。基本上,我正在创建一个shell并通过stdin将类似"exec wc -c;\n<data>"的字符串发送到shell。

我正在寻找启动子流程并将数据传递给所述子流程。 使用exec我完全期望wc -c替换我的shell并计算通过stdin发送的字节数。

示例:

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一致,但不是使用破折号或busybox sh。他们似乎都断断续续地失败了。如果我在通过stdin发送<data>之前睡了100毫秒,那么它可以工作。但是睡觉不是一个可靠的解决办法。

实际上,我发送的是非常重要的数据,所以我不想对其进行编码或以某种方式将其存储在内存中。有什么想法吗?

注意:我确定有很多用例可以解决这个问题。但是我想找出为什么这种情况不能持续发挥作用。和/或我可以做些什么来使其可靠地工作,最好是跨平台:)

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

基本上,我希望证明只使用sh的stdin来控制系统。其他非常简单的,而不是sh,可以跨平台随时使用,因为静态二进制文件也可以使用。

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

1 个答案:

答案 0 :(得分:1)

这对我来说对bash有用,但对于破折号或busybox sh来说根本不适用。我很惊讶它一直在工作。我希望shell能够从stdin读取大量的输入,包括第一行的命令和之后的数据,然后再处理任何内容。这将在exec&#39; ed命令的stdin上留下任何东西。

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

破折号和busybox sh完全符合我的预期,首先阅读整个输入。

你能做到吗

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

代替?如果你担心它会出现在输入中,可能会用END_adjfioe38999f3jf_END替换END吗?

更新:虽然想到这一点,但这会使你的内存中没有缓冲区&#34;标准。呃...好吧,这很难。如果你可以保证命令运行在4k以内,那么像这样可怕的事情将会工作&#34;:

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,通过管道连接,将剩余的初始块发送到管道,将自己的stdout复制到管道,然后execs cat一次将stdin复制到管道上,管道将在stdin上接收它。我认为这就是你想要最终发生的事情,只需要更简单的基于shell的语法。