【问题标题】:using python's subprocess in a cli function breaks the comamnd line在 cli 函数中使用 python 子进程会破坏命令行
【发布时间】:2017-03-08 22:48:32
【问题描述】:

我已经编写了一个 python 脚本来批处理视频文件,并且我已经为它创建了一个 CLI 绑定。您可以找到存储库here

作为脚本的一部分(因为视频处理是计算密集型的)我是using Python's subprocess module to achieve some parallelization

我从命令行调用我的脚本为:

repositorg vidproc -p "-crf 16 -c:a copy -filter:v 'crop=1080:1080:420:0'" nd750_a00{80..86}.MOV

而且效果很好。但是,执行后,它会破坏我的终端。我再也看不到我正在输入的内容,但它仍会发送到终端。这是我杀死当前行几次,然后输入ls 并按回车的示例:

chymera@zenbookhost ~/data/cameras/nd750/a $ ^C
chymera@zenbookhost ~/data/cameras/nd750/a $ ^C
chymera@zenbookhost ~/data/cameras/nd750/a $ ^C
chymera@zenbookhost ~/data/cameras/nd750/a $ ^C
chymera@zenbookhost ~/data/cameras/nd750/a $ nd750_a0000.mkv  nd750_a0016.mkv  nd750_a0032.mkv  nd750_a0048.mkv  nd750_a0064.mkv  nd750_a0079.MOV
nd750_a0001.mkv  nd750_a0017.mkv  nd750_a0033.mkv  nd750_a0049.mkv  nd750_a0065.mkv  nd750_a0080.mkv
nd750_a0002.mkv  nd750_a0018.mkv  nd750_a0034.mkv  nd750_a0050.mkv  nd750_a0066.mkv  nd750_a0080.MOV
nd750_a0003.mkv  nd750_a0019.mkv  nd750_a0035.mkv  nd750_a0051.mkv  nd750_a0067.mkv  nd750_a0081.mkv
nd750_a0004.mkv  nd750_a0020.mkv  nd750_a0036.mkv  nd750_a0052.mkv  nd750_a0068.mkv  nd750_a0081.MOV
nd750_a0005.mkv  nd750_a0021.mkv  nd750_a0037.mkv  nd750_a0053.mkv  nd750_a0069.mkv  nd750_a0082.mkv
nd750_a0006.mkv  nd750_a0022.mkv  nd750_a0038.mkv  nd750_a0054.mkv  nd750_a0070.mkv  nd750_a0082.MOV
nd750_a0007.mkv  nd750_a0023.mkv  nd750_a0039.mkv  nd750_a0055.mkv  nd750_a0071.mkv  nd750_a0083.mkv
nd750_a0008.mkv  nd750_a0024.mkv  nd750_a0040.mkv  nd750_a0056.mkv  nd750_a0072.mkv  nd750_a0083.MOV
nd750_a0009.mkv  nd750_a0025.mkv  nd750_a0041.mkv  nd750_a0057.mkv  nd750_a0073.mkv  nd750_a0084.mkv
nd750_a0010.mkv  nd750_a0026.mkv  nd750_a0042.mkv  nd750_a0058.mkv  nd750_a0074.mkv  nd750_a0084.MOV
nd750_a0011.mkv  nd750_a0027.mkv  nd750_a0043.mkv  nd750_a0059.mkv  nd750_a0075.mkv  nd750_a0085.mkv
nd750_a0012.mkv  nd750_a0028.mkv  nd750_a0044.mkv  nd750_a0060.mkv  nd750_a0076.mkv  nd750_a0085.MOV
nd750_a0013.mkv  nd750_a0029.mkv  nd750_a0045.mkv  nd750_a0061.mkv  nd750_a0077.mkv  nd750_a0086.mkv
nd750_a0014.mkv  nd750_a0030.mkv  nd750_a0046.mkv  nd750_a0062.mkv  nd750_a0078.mkv  nd750_a0086.MOV
nd750_a0015.mkv  nd750_a0031.mkv  nd750_a0047.mkv  nd750_a0063.mkv  nd750_a0079.mkv

如您所见,ls 没有打印出来,但它的输出是,虽然从提示符开始...

我想知道:

  • 这是怎么回事?
  • 一旦发生这种情况,我该如何修复我的终端?
  • 如何防止我的脚本破坏终端?

【问题讨论】:

    标签: python linux bash shell subprocess


    【解决方案1】:

    某些进程可能已关闭echo。这可以使用stty 命令进行检查。通常会发生这种情况:

    $ stty
    speed 38400 baud; line = 0;
    -brkint ixoff -imaxbel iutf8
    

    如果它被关闭:

    $ stty -echo
    

    然后按回车键 4 次,输入stty:

    $ $ $ $ $ speed 38400 baud; line = 0;
    -brkint ixoff -imaxbel iutf8
    -echo
    

    要重新打开它,只需致电stty echo

    【讨论】:

      【解决方案2】:

      捕获键盘中断并干净地处理它。 https://docs.python.org/3/library/exceptions.html#KeyboardInterrupt

      注意,在多进程环境中,您需要考虑到中断可能发生在任何地方(在工作线程或父线程中),您应该在退出父线程之前杀死所有工作线程。

      【讨论】:

      • 这个问题不是在我中断函数时发生的,而是在它完成执行之后发生的。
      【解决方案3】:

      我还没有弄清楚问题到底是什么(并且很高兴接受将信息添加到此答案的编辑),但似乎我需要终止脚本进程以使用户返回到干净的提示。我通过附加以下to my function

      while None in [p.poll() for p in processes]:
          time.sleep(0.5)
      #We need to explicitly terminate the master process here, as otherwise the shell "hangs" and the user needs to press enter to return to a new prompt.
      os.system('kill %d' % os.getpid())
      

      【讨论】:

        猜你喜欢
        • 2012-05-22
        • 2019-07-27
        • 1970-01-01
        • 1970-01-01
        • 2017-05-30
        • 1970-01-01
        • 2015-10-29
        • 2020-07-25
        • 2021-12-07
        相关资源
        最近更新 更多