subprocess.Popen command with quoted argument fails with shell=False

Question:

I’m trying to change the creation date metadata of a file on macOS using python. The macOS shell command to do that is SetFile -d '01/03/2012 12:00:00 PM' /path/to/file.
I’m using the subprocess module to run a shell command in python, here is my code:

import subprocess

path = '/Users/marinnagy/Desktop/banner.jpg'
subprocess.Popen(['SetFile', '-d', '"01/03/2012 12:00:00 PM"', path])

No error occurs when running the script and the creation date of the file changes but to the wrong date. For this example, the date is changed to December 4th, 2011 (12/04/2011) instead of January 3st 2012. The shell command works well when used from the terminal, but the date is goes wrong when called from subprocess.

Here is some information about the SetFile command, the date format is mm/dd/[yy]yy [hh:mm:[:ss] [AM | PM]]

Why is date wrong when using the command from subprocess, and how to fix it? Maybe I miss something, my computer is set to the french time format (dd/mm/yyyy) but doesn’t seems to be linked.

Asked By: Marin Nagy

||

Answers:

You’ve got too many quotes. The double quotes around the date format are only needed for the shell, so it doesn’t split the argument at whitespace, and the shell strips off those quotes so SetFile doesn’t see them.

If you were running with shell=True, passing a str instead of a list, you’d need them (e.g. subprocess.Popen(f'SetFile -d "01/03/2012 12:00:00 PM" {shlex.quote(path)}', shell=True)), but with the default shell=False (the correct way to use subprocess, being more efficient, stable, portable, and more secure against malicious input), you do the splitting yourself and the only quotes needed are those for Python string literals.

Since you’re running without a shell, with a list of arguments, you’ve presplit the arguments already, and those interior double-quotes are passed verbatim, likely violating the expected format for your program.

Try just using:

subprocess.Popen(['SetFile', '-d', '01/03/2012 12:00:00 PM', path])
#                                   ^                    ^ double quotes removed
Answered By: ShadowRanger
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.