所以,我有一个在没有屏幕的嵌入式Linux ARM平台上运行的交互式程序,我无法修改。要与它交互,我必须ssh进入嵌入式Linux发行版,并运行程序,这是一种带内置命令的自定义命令行,并且它不会退出,只有SIGINT将退出该程序。
我尝试通过让它在后台运行并使用管道通过发送像这样ssh user@host echo "command" > stdinpipe
的SSH命令与它进行通信来尝试自动化它。这部分有效,我在shell脚本中提供了这样的例子(我不能使用bash,我只在机器上安装了灰):
#!/bin/sh
mkfifo somePipe
/proc/<PID>/exe < somePipe 2>&1 &
我现在可以通过写入管道来轻松地命令程序,如
echo "command" > somePipe
它输出终端内的所有内容。问题在于,如果我打开了一个SSH会话,它就可以工作了,如果我只是按照前面的说法逐个发送命令,那就不行了(我在python中使用paramiko和exec_command()
方法,以防万一,但我不认为这是相关的,我可以使用invoke_session()
,但我不想要处理recv()
)
所以我发现我将程序的输出重定向到管道。那就是问题出现的地方。我的第一次尝试就是这个(请忽略这样一个事实:一切都以root身份运行并存储在root主文件夹中,这就是我如何得到它而且我现在没有时间让它变得更干净,加上我不是管理软件的人:
cd /root/binary
mkfifo outpipe
mkfifo inpipe
./command_bin &
# find PID automatically
command_pid=$(ps -a | egrep ' * \.\/command_bin *' | grep -v grep | awk '{print $1}')
/proc/${command_pid}/exe < inpipe 2>&1 &
echo "process ./command_bin running on PID ${command_pid}"
仅在终端本身内工作。现在,如果我打开SSH会话并打开另一个终端并输入ssh root@host "echo command > /root/binary/inpipe"
代码将被执行,但它会输出我刚刚输入的命令,并将其结果输出到另一个保持打开的终端。所以它显然不是一个选项,我必须以某种方式捕获输出。
如果我为./command_bin &
更改了./command_bin >outpipe &
,程序永远不会启动,我不知道为什么,我知道因为$command_pid
为空而我找不到{{1}的流程}
现在,如果我将ps -A
替换为/proc/${command_pid}/exe < inpipe 2>&1 &
程序启动,我可以在脚本完成运行时用/proc/${command_pid}/exe < inpipe &>outpipe &
写入inpipe,但是如果我尝试echo "command" > inpipe
1}},cat < outpipe
它只是挂起,什么都不做。我在启动命令时尝试使用tail outpipe
,但它并没有真正帮助。我也尝试使用普通文件重定向输出而不是fifo,但结果完全相同。
我花了一整天的时间来处理这件事,我无法让它发挥作用。为什么这不起作用?另外我可能只是用一种糟糕的方式来做到这一点,还有其他方法吗?这里唯一强制的是我必须通过ssh连接到电路板,命令行实用程序必须保持打开状态,因为它正在与板载设备通信(使用I2C,OneWire协议等)。
为了保持简单,我希望能够随时写入程序的stdin,让它的stdout去别的地方(一些文件,缓冲区,我不在乎)我以后可以轻松找到经过一段任意的时间,用cat,tail或其他命令用ssh。