subprocess.call() - 无法解析JSON(词法错误:json文本中的无效字符。)

时间:2014-10-25 18:35:31

标签: python json subprocess

我试图修改python脚本来运行shell程序,我用subprocess.call()这样做:

def on_leftclick(self):
    import subprocess
    subprocess.call("mpc toggle", shell=True)

当我左键单击时出现此错误:

Could not parse JSON (lexical error: invalid char in json text.)

这是在i3pystatus中完成的,这是一个与i3bar(i3窗口管理器的一部分)连接的程序,我已经修改了另一个脚本并且它工作了,例如:

def on_upscroll(self):
    import subprocess
    subprocess.call("pamixer --increase 1 --allow-boost", shell=True)

另外,我试过这样做:

import subprocess
subprocess.call("mpc toggle", shell=True)

在python shell中它起作用了,所以我不知道问题所在。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

这是由于在i3pystatus模块中执行此操作引起的:

subprocess.call("mpc toggle") # parameter shell=True or False, doesn't matter

因为默认情况下,No coverage when running in watch mode函数将父进程(即stdout)的stderri3pystatus文件句柄传递给新的子项(mpc ),您的mpc调用中的所有输出都将转储到i3pystatus自己的输出中。该输出应该是有效的JSON,但现在其中有大量意外的随机控制台。这导致i3pystatus的输出无法解析为JSON。*

您有两个选择:

使用subprocess捕获/处置子流程的输出

处理:

def on_leftclick(self):
    subprocess.call("mpc toggle", shell=True, 
                    stdout=subprocess.DEVNULL)

或者,如果需要输出,请subprocess.call()

def on_leftclick(self):
    p = subprocess.Popen(['mpc', 'toggle'],
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    out, err = p.communicate() # .decode() these to strings if appropriate
    retcode = p.returncode

在i3pystatus中使用run_through_shell助手

i3pystatus为您提供了一个包装subprocess的助手:subprocess.Popen()

from i3pystatus.core.command import run_through_shell

def on_leftclick(self):
    run_through_shell(["mpc", "toggle"])

或者,要让您的shell进行命令的解析,请给它提供字符串:

def on_leftclick(self):
    run_through_shell("mpc toggle", enable_shell=True)

出于您自己的邪恶目的,您还可以轻松获得返回码和stdout / stderr输出:

def on_leftclick(self):
    retcode, out, err = run_through_shell(["mpc", "toggle"])
    # out and err are already decoded to UTF-8 - you can't use this
    # method if that's not true, e.g. if it's binary data

为公平起见,run_through_shell直到提出问题的第二年才出现(i3pystatus.core.command.run_through_shell)。 i3pystatus在代码库中同时使用了这两种方法。

  

TL; DR:确保您的子进程没有将输出喷入   i3pystatus的输出,因为它必须是有效的JSON。

*可能无法added in December 2014进入json.loads(),但是我还没有证明。