pythonbashsubprocessbackticks

Python: How to use backticks in subprocess?


I would like to run a subprocess from Python. Inside the command string are several subcommands with backticks:

subprocess = subprocess.Popen(
    [
        "echo",
        "COMMAND [`date +%%s`] SCHEDULE_HOST_DOWNTIME;%s;`date +%%s`;`date -d 'now + %d sec' +%%s`;1;;;%s;Downtime comment" % (hostname, 300, username)
    ],
    stdout=subprocess.PIPE
)

Though the date commands in the back ticks are not executed. The stdout of this command is:

COMMAND [`date +%s`] SCHEDULE_HOST_DOWNTIME;example.com;`date +%s`;`date -d 'now + 300 sec' +%s`;1;;;my-username;Downtime comment

I also tried to use $(date +%s) instead of backticks and explicitly sent it to bash via subprocess.Popen(["/bin/bash", "-c", "echo", "..."], with the same result.

How can this be solved? I know I can of course use Pythons datetime module in this specific case. But I want to know why this is not working and how to solve it without tearing apart the command. While I'm here able to run the timestamp calculation easily in Python, in other cases it might be more complicated, where I would be forced to run several subprocesses which gets quickly very ugly.


Solution

  • Backticks are a shell syntax feature, but you are not running your command in a shell. The subprocess module runs the command directly.

    Provide one string rather than a list, and set shell=True if the shell needs to process the command as one entry:

    subprocess = subprocess.Popen(
        'echo "COMMAND [`date +%%s`] SCHEDULE_HOST_DOWNTIME;%s;`date +%%s`;`date -d \'now + %d sec\' +%%s`;1;;;%s;Downtime comment"' % (hostname, 300, username),
         stdout=subprocess.PIPE
         shell=True)