'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 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()

The first argument to Popen is a list of arguments, unless shell=True and that is not recommended.

Solution 2:[2]

That error is because you have to use triple " for multiline string literal.

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

But I recommend you to create a file with the script, and then run it using Popen.

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

Anyway if the script don't change, there is no need to keep it in a variable in your code.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Anton
Solution 2