【问题标题】:How to write a python script to interact with shell scripts如何编写 python 脚本与 shell 脚本交互
【发布时间】:2016-10-25 07:34:15
【问题描述】:

我在工作中遇到了问题。在这里。

我有几个脚本(主要是 shell 脚本)要执行,我想编写一个 python 脚本来自动运行它们。其中一个 shell 脚本在执行期间需要交互式输入。困扰我的是我找不到读取它的输入提示的方法,所以我无法决定输入什么来继续。

我将问题简化为:

有一个名为mediator.py 的脚本,它在里面运行greeter.shmediator 接受greeter 的输入提示并将其打印给用户,然后获取用户的输入并将其传递给greeter。从用户的角度来看,mediator 的行为必须与 greeter 完全相同。

这里是greeter.sh

#! /bin/bash
echo "Please enter your name: " # <- I want 'mediator.py' to read this prompt and show it to me, and then get what I input, then pass my input to 'greeter.sh'
read name 
echo "Hello, " $name

我想按以下顺序执行此操作:

  1. 用户(就是我)运行mediator.py
  2. mediator 在内部运行 greeter.sh
  3. mediator得到greeter的输入提示,并输出到屏幕上。(此时greeter正在等待用户输入。这是我坚持的主要问题)
  4. 用户输入一个字符串(例如,'Mike'),mediator获取字符串'Mike'并传送给greeter
  5. greeter 获得名称“Mike”,并打印问候语
  6. mediator 获取问候语,并将其输出到屏幕上。

我搜索了一些解决方案,并决定在subprocess模块中使用Popen函数,子进程的stdout指向PIPE,它是这样的:

sb = subprocess.Popen(['sh', 'greeter.sh'], stdout = subprocess.PIPE, stdin = stdout, stderr = stdout)

但我无法解决上述第 3 步中的主要问题。任何人都可以给我一些帮助的建议吗?非常感谢!

【问题讨论】:

    标签: python shell subprocess nonblocking python-interactive


    【解决方案1】:

    你让它变得比它必须的更复杂(和脆弱)。与其在顶层编写所有代码并尝试使用子进程或其他任何方式来使用脚本,就好像它们在函数中一样,只需编写模块和函数并从主脚本中使用它们。

    这是一个示例,所有内容都包含在脚本本身中,但如果您需要在不同脚本之间共享某些功能,您可以将其拆分为不同的模块

    # main.py
    def ask_name():
        return raw_input("Please enter your name: ")
    
    def greet(name):
        return "Hello, {} name !\n".format(name)
    
    def main():
        name = ask_name()
        print greet(name)
    
    if __name__ == "__main__":
        main()
    

    【讨论】:

    • 首先感谢您的回答。我想出了这个使用场景,因为我在工作中遇到了它。我有几个 shell 脚本要运行,我想编写一个 python 脚本来自动运行它们。其中一个shell脚本需要用户在执行过程中输入一些选项,所以我需要得到shell脚本的提示,然后确定输入哪个选项以继续执行。就是这样。
    • 你应该在这个上下文中编辑你的问题 - 这是一个不同的问题。我将留给subprocess 专家 FWIW...
    • 谢谢~问题已经重新描述了。
    • 我把之前的greeter.py代码去掉,用shell脚本改写成greeter.sh,这样就更符合我的使用场景了