【问题标题】:Call an external command in Python在 Python 中调用外部命令
【发布时间】:2016-09-30 16:11:45
【问题描述】:

如何从 Python 脚本中调用外部命令(就像我在 Unix shell 中输入的一样)?

我试过这段代码:

from subprocess import call
call(["ls", "-l"])

它有效。 但是当我在 Python 脚本中尝试这段代码时:

from subprocess import call
call(['sox', '/home/pi/OnoSW/data/opsoroassistant/rec.wav', '-n', 'stat', '2>&1', '|', 'sed', '-n', 's#^RMS     amplitude:[^0-9]*\([0-9.]*\)$#\1#p'])

它不起作用。我收到此错误:

 sudo python getRMSAmplitude.py sox FAIL stat: Summary effect: unknown option

当我在我的 Unix Shell 中输入这个命令时:

sox ../../data/opsoroassistant/rec.wav -n stat 2>&1 | sed -n 's#^RMS     amplitude:[^0-9]*\([0-9.]*\)$#\1#p'

我明白了:

0.001754

什么是正确的。

【问题讨论】:

    标签: python shell command subprocess sox


    【解决方案1】:
    call([...], shell=True)
    

    目前发生的情况是,您提供的其余参数 '2>&1', '|', 'sed', '-n', 's#^RMS amplitude:[^0-9]*\([0-9.]*\)$#\1#p'] 正在被 sox 解释为参数,因为没有 shell 来解释输出重定向或管道。告诉call 使用shell,它的解释方式与您的命令行相同。

    【讨论】:

    • 谢谢,现在我没有错误,但是当我运行脚本时,它没有返回任何值。与 os.system("...") 相同。我必须打印出来还是什么?
    • 不知道为什么要投反对票,但没关系。不,call 只是运行程序,它不返回任何输出。您需要 subprocess.check_output 将进程写入 stdoutstderr 的任何内容放入变量中。
    • 好吧,我试过这个:output = subprocess.check_output(['ls', '-1']) print 'Have %d bytes in output' % len(output) print output,我有 99 个字节的输出和输出,一个文件和目录列表。然后我尝试了这个:output = subprocess.check_output(["sox /home/pi/OnoSW/data/opsoroassistant/rec.wav -n stat 2>&1 | sed -n 's#^RMS amplitude:[^0-9]*\([0-9.]*\)$#\1#p'"], shell=True) print 'Have %d bytes in output' % len(output) print output,我把它作为输出:Have 2 bytes in output,但不是输出本身。
    • 对于callcheck_output 和其他人,您可以提供一个包含单个元素的列表,例如['ls', '-1'] 或一个字符串,"ls -1" - 在第二个示例中,您有一个包含一个的列表长串。当你只使用字符串而不是列表时会发生什么?
    • 如果不是列表,您的确切含义是什么?
    【解决方案2】:

    你也可以使用os.system:

    import os
    os.system("sox ../../data/opsoroassistant/rec.wav -n stat 2>&1 | sed -n 's#^RMS     amplitude:[^0-9]*\([0-9.]*\)$#\1#p'")
    

    【讨论】:

      【解决方案3】:

      另一个选项(更容易使用)是 os.system('your original command')

      import os
      os.system("sox ../../data/opsoroassistant/rec.wav -n stat 2>&1 | sed -n 's#^RMS     amplitude:[^0-9]*\([0-9.]*\)$#\1#p'")
      

      【讨论】:

        【解决方案4】:

        调用函数中的参数应该和命令在同一个字符串中。

        call('sed -arg1 -arg2 -argn')
        

        【讨论】:

        • 只有设置了shell=True,否则会认为sed -arg1 -arg2 -argn是一个文件名带空格的可执行文件
        猜你喜欢
        • 1970-01-01
        • 2011-11-18
        • 2015-08-29
        • 1970-01-01
        • 2019-01-14
        • 2012-04-06
        • 1970-01-01
        • 2020-10-31
        • 2015-06-13
        相关资源
        最近更新 更多