pythondtrace

How to supply multi line command to subprocess.Popen?


I need to be able to run a multi line dtrace script via python subprocess.Popen, and tried this... have the following code snippet in python but this does not work, what is the correct approach for handling such templates?

    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

Using the quotes does not help enclose the multi line command into cmd. Get the following error when attempted to run SyntaxError: EOL while scanning string literal


Solution

  • There're a couple things happening here. The SyntaxError: EOL while scanning string literal is because you've tried to create a multi-line string with just a double-quote, which isn't legal in python. You can do it with a triple double-quote:

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

    The second problem you'll have is that by default, subprocess.Popen wants an array of strings, not a space-separated shell command. You can pass Popen a shell=True argument to make it accept a string like you have here. Alternatively, break the command into pieces and just put the dtrace script in your multi-line string:

    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)