如何执行一个接受 python 输入的 shell 程序?

How to execute a shell program taking inputs with python?

首先,我使用的是 Ubuntu 20.04 和 Python 3.8。 我想要 运行 一个接受命令行输入的程序。我设法使用 os.system() 命令从 python 启动程序,但启动程序后无法发送输入。该程序是一个使用 CubeSat Space 协议 (CSP) 作为语言的产品接口应用程序。然而,使用的输入被编码在一个 .c 文件及其相应的 .h header.

在 shell 中,它看起来像这样: starting the program

在python中,它看起来像这样:

import os
os.chdir('/home/augustin/workspaceGS/gs-sw-nanosoft-product-interface-application-2.5.1')
os.system('./waf')
os.system('./build/csp-client -k/dev/ttyUSB1')
os.system('cmp ident') #cmp ident is typically the kind of command that does not work on python

输出与shell相同,但没有“cmp ident输出”,也就是说我不可能使用csp-client#

正如您可能看到的那样,我是一个真正的初学者,试图尽可能清晰和准确。如果需要,我当然可以尝试提供更多信息。感谢您的帮助!

我会尝试给你一些提示让你开始 - 尽管记住我不知道你的任何工具,即 wafcsp-client,但希望不会事.

我将对我的观点进行编号,以便您轻松参考这些步骤。


点 1

如果 waf 是构建系统,我不会在每次您想 运行 您的 csp-client 时保留 运行ning。更改代码后,只需使用 waf 进行重建 - 这样可以节省时间。


点 2

当您将目录更改为 /home/augustin/workspaceGS/gs-sw-nanosoft-product-interface-application-2.5.1 然后 运行 ./build/csp-client 您实际上是 运行ning:

/home/augustin/workspaceGS/gs-sw-nanosoft-product-interface-application-2.5.1/build/csp-client -k/dev/ttyUSB1

但这很烦人,所以我会为 /usr/local/bin 中的那个创建一个符号 link,这样你就可以 运行 它只用:

csp-client -k/dev/ttyUSB1

所以,我会用以下方式创建 symlink:

ln -s /home/augustin/workspaceGS/gs-sw-nanosoft-product-interface-application-2.5.1/build/csp-client  /usr/local/bin/csp-client

您可能需要在该命令的开头放置 sudo。一旦你有了它,你应该能够 运行:

csp-client -k/dev/ttyUSB1

点 3

您的 Python 代码不起作用,因为每个 os.system() 开始一个全新的 shell,与上一行或 shell 无关。然后它启动的 shell 在您的下一个 os.system() 命令之前退出。

因此,cmp ident 命令永远不会转到 csp-client。您确实需要在 csp-clientstdin“标准输入” 上发送 cmp ident 命令。你 可以 在 Python 中做到这一点,here 对此进行了描述,但对于初学者来说并不是那么容易。

相反,如果您只需要发送一些有限的命令,例如“拍照”,我会完成并测试bash 终端中的脚本,直到我把它们弄对了,然后才从 Python 中调用它们。所以,我会在你的 HOME 目录中创建一个 bash 脚本,比如 csp-snap 并在其中放入这样的东西:

#/bin/bash

# Extend PATH so we can find "/usr/local/bin/csp-client"
PATH=$PATH:/usr/local/bin

{
   # Tell client to take picture
   echo "nanoncam snap" 
   # Exit csp-client
   echo exit
} | csp-client -k/dev/ttyUSB1

现在使该可执行文件(只需要一次):

chmod +x $HOME/csp-snap

然后你可以测试它:

$HOME/csp-snap

如果可行,您可以使用以下命令将脚本复制到 /usr/local/bin

cp $HOME/csp-snap /usr/local/bin

您可能需要 sudo 再次开始。

那么你应该可以从任何地方拍照:

csp-snap

那么你的 Python 代码就变得简单了:

os.system('/usr/local/bin/csp-snap')

听起来 pexpect 模块可能是您正在寻找的,而不是使用 os.system 它设计用于控制其他应用程序并像人类使用它们一样与它们交互。它的文档可用 here。但你想要的可能看起来像这样:

import pexpect
p = pexpect.spawnu("/home/augustin/workspaceGS/gs-sw-nanosoft-product-interface-application-2.5.1/build/csp-client -k/dev/ttyUSB1")
p.expect("csp-client")
p.sendline("cmp indent")
print(p.read())
p.close()