如何为subprocess.Popen提供多行命令?

时间:2014-08-25 17:42:55

标签: python dtrace

我需要能够通过python subprocess.Popen运行多行dtrace脚本,并尝试了这个...在python中有以下代码片段但是这不起作用,处理这些模板的正确方法是什么?

    cmd = "/usr/sbin/dtrace -n '
    #pragma D option quiet
    profile:::profile-1001hz
    /arg0/
    {
            \@pc[arg0] = count();
    }
    dtrace:::END
    {
            printa("%a %\@d\\n", \@pc);
    }'"

    def execute_hotkernel():
    proc = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
    (output, error) = proc.communicate()
    print output

使用引号无法将多行命令封装到cmd中。尝试运行SyntaxError: EOL while scanning string literal

时出现以下错误

3 个答案:

答案 0 :(得分:1)

该错误是因为您必须将三"用于多行字符串文字。

 s = """#pragma D option quiet
    profile:::profile-1001hz
    /arg0/
    {
            \@pc[arg0] = count();
    }
    dtrace:::END
    {
            printa("%a %\@d\\n", \@pc);
    }"""

但我建议您使用脚本创建一个文件,然后使用Popen运行它。

subprocess.Popen(['/usr/sbin/dtrace', 'script_you_have_just_created.td'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

无论如何,如果脚本没有改变,则无需将其保存在代码中的变量中。

答案 1 :(得分:1)

arg3 = '''
#pragma D option quiet
profile:::profile-1001hz
/arg0/
{
        \@pc[arg0] = count();
}
dtrace:::END
{
        printa("%a %\@d\\n", \@pc);
}
'''
proc = subprocess.Popen(['/usr/sbin/dtrace', '-n', arg3], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()

Popen的第一个参数是一个参数列表,除非shell=True,不推荐使用。{/ p>

答案 2 :(得分:1)

这里发生了一些事情。 SyntaxError: EOL while scanning string literal是因为你试图用双引号创建一个多行字符串,这在python中是不合法的。你可以使用三重双引号:

cmd = """/usr/sbin/dtrace -n '
#pragma D option quiet
...
"""

您遇到的第二个问题是,默认情况下,subprocess.Popen需要一个字符串数组,而不是空格分隔的shell命令。您可以传递Popen一个shell=True参数,使其接受您在此处的字符串。或者,将命令分成几部分,然后将dtrace脚本放在多行字符串中:

dtrace_script = """#pragma D option quiet
profile:::profile-1001hz
/arg0/
{
        \@pc[arg0] = count();
}
dtrace:::END
{
        printa("%a %\@d\\n", \@pc);
}
"""
...
subprocess.Popen(['/usr/sbin/dtrace', '-n', dtrace_script], stdout=subprocess.PIPE, stderr=subprocess.PIPE)