2

I'm trying to call an executable that has parentheses in the name (e.g. 'test(1).exe').

With Python 3.6.2, when I try the following:

os.system('test(1).exe')

I get:

'test' is not recognized as an internal or external command, operable program or batch file.

But if I change the filename to 'test1).exe' by removing '(', then the following works successfully:

os.system('test1).exe')

Any ideas why the left parenthesis is causing an issue with os.system?

martineau
  • 119,623
  • 25
  • 170
  • 301
mendlo
  • 47
  • 3
  • try with this `test\ \(1\).exe' inside `os.system()` – Achal Dec 17 '17 at 07:47
  • 5
    You need to escape shell special characters / separators if you're going to use `os.system()`. Or, from the documentation of the same function: '_The [`subprocess`](https://docs.python.org/2/library/subprocess.html#module-subprocess) module provides more powerful facilities for spawning new processes and retrieving their results; **using that module is preferable to using this function**. See the [Replacing Older Functions with the subprocess Module](https://docs.python.org/2/library/subprocess.html#subprocess-replacements) section in the subprocess documentation for some helpful recipes._' – zwer Dec 17 '17 at 07:54
  • 1
    If you're using Windows (as it appears), then you need to "escape" certain characters. Here's what it says about it in a Windows command-line reference help file I have: "The ampersand (`&`), pipe `(|`), and parentheses (`(` and `)`) are special characters that **must be preceded** by the escape character (`^`) or quotation marks when you pass them as arguments." (emphasis mine) – martineau Dec 17 '17 at 15:40
  • Found some online documentation about it on the [SS64 command-line reference](https://ss64.com/) website in a section titled [Syntax : Escape Characters, Delimiters and Quotes](https://ss64.com/nt/syntax-esc.html) – martineau Dec 17 '17 at 15:49

2 Answers2

3

Using subprocess.call() without shell=True avoids the need to quote arguments in a shell-safe manner:

subprocess.call(["test(1).exe"])
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • You can omit ".exe" to help with cross-platform code. If `shell=True` is required for some reason, then the executable name needs to be quoted with double quotes, and pass the command line as a string instead of a list, e.g. `subprocess.call('"test(1)"', shell=True)`. – Eryk Sun Dec 17 '17 at 22:40
1

Solution: put a '^' character in front of '(' like this:

os.system('test^(1).exe')
mendlo
  • 47
  • 3