【问题标题】:How to execute a shell program taking inputs with python?如何执行使用 python 输入的 shell 程序?
【发布时间】:2021-11-12 13:57:21
【问题描述】:

首先,我使用的是 Ubuntu 20.04 和 Python 3.8。 我想运行一个接受命令行输入的程序。我设法使用 os.system() 命令从 python 启动程序,但启动程序后无法发送输入。有问题的程序是使用 CubeSat 空间协议 (CSP) 作为语言的产品界面应用程序。但是,使用的输入被编码在一个带有相应 .h 标头的 .c 文件中。

在 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 output”,也就是说我不可能使用csp-client#

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

【问题讨论】:

  • 顺便说一句,我对 CSP 一无所知...你的意思是你想编写一个 Python 脚本来发送一些你已经提前知道的 CSP 命令吗?或者你的意思是你想写一个 Python 脚本来询问你的输入,读取你输入的内容并将它传递给 CSP 并显示结果? waf 是什么?你发的命令是什么?有什么东西连接到 USB 端口吗?什么?
  • 为了看看你的程序是如何工作的,你可以尝试非交互地运行它吗?那么,如果您要发送的命令是cmp ident,您可以运行echo "cmp ident" | csp-client -k/dev/ttyUSB1 看看它是否能正常工作吗?
  • 我给你的信息太少,这是我的错:我正在使用一个使用 CSP 作为协议的纳米卫星成像仪,并且这个成像仪是通过命令行控制的(例如,命令“nanocam snap”会拍照)。当然,这些命令被编码在一个带有相应标题的 C 文件中。因此,将 RS232 转 USB 转换器插入 USB1 端口。 Waf 是一个基于 Python 的构建系统 (waf.io/book)。关于 Python,最终代码旨在按下 GUI 中的按钮以拍照,而不使用命令行,但现在我无法访问 cap-client#
  • 我只是试图运行你告诉我的,它不适用于这个确切的命令,但它适用于 echo "cmp ident" | ./csp-client -k/dev/ttyUSB1 但是我真的不明白它对我有什么帮助,但我'我会考虑的
  • 请输入什么命令退出csp-client

标签: python-3.x shell command-line-interface os.system cubesat-protocol


【解决方案1】:

听起来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()

【讨论】:

    【解决方案2】:

    我会尝试为您提供一些提示以帮助您入门 - 尽管请记住,我不知道您的任何工具,即 wafcsp-client,但希望这不会有什么问题。

    我会给我的分数编号,以便您轻松参考步骤。


    第 1 点

    如果waf 是一个构建系统,我不会在您每次想要运行csp-client 时都继续运行它。更改代码后,只需使用 waf 重新构建 - 这样可以节省时间。


    第 2 点

    当您将目录更改为/home/augustin/workspaceGS/gs-sw-nanosoft-product-interface-application-2.5.1 然后运行./build/csp-client 时,您正在有效地运行:

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

    但这很烦人,所以我会从/usr/local/bin 建立一个符号链接,这样你就可以运行它:

    csp-client -k/dev/ttyUSB1
    

    所以,我将使用以下符号链接:

    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。您确实需要在stdincsp-client“标准输入” 上发送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')
    

    【讨论】:

    • 我按照您的指示操作,效果很好!非常感谢
    • 太棒了 - 干得好,祝你的项目好运。如果您遇到困难,请回来问一个新问题 - 问题(和答案)是免费的 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 2012-03-09
    • 1970-01-01
    • 2014-05-03
    • 2021-08-01
    • 2021-05-15
    • 1970-01-01
    相关资源
    最近更新 更多