This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: subprocess.call() fails for .bat files on Windows, if executable path contains parenthesis
Type: behavior Stage: resolved
Components: Library (Lib), Windows Versions: Python 3.1, Python 2.6
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: tim.golden Nosy List: brian.curtin, sandberg, tim.golden
Priority: normal Keywords:

Created on 2009-03-13 14:32 by sandberg, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
parenbug.py sandberg, 2009-03-13 14:32 Script that reproduces the error
parenbug.c sandberg, 2009-03-13 17:07 C program that demonstrates how CreateProcess works
Messages (10)
msg83518 - (view) Author: Erik Carstensen (sandberg) Date: 2009-03-13 14:32
When subprocess.call is told to execute a .bat file on Windows, and the
path to the batch file is given as an absolute path, and the path
includes a left parenthesis ('('), then the call fails with a message
similar to the following; it appears that the parenthesis is incorrectly
quoted.

'c:\tmp\f' is not recognized as an internal or external command,
operable program or batch file.
Traceback (most recent call last):
  File "parenbug.py", line 7, in <module>
    subprocess.check_call(os.path.join(os.getcwd(), bat))
  File "c:\Python25\lib\subprocess.py", line 461, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'c:\tmp\f(o.bat' returned
non-zero exit status 1

I have reproduced this on Windows XP.
msg83519 - (view) Author: Erik Carstensen (sandberg) Date: 2009-03-13 14:34
I'm using Python 2.5.1, by the way.
msg83520 - (view) Author: Erik Carstensen (sandberg) Date: 2009-03-13 16:34
I have narrowed down the problem further: The same error happens with
the following code:

import win32process
win32process.CreateProcess(None, 'f(o.bat', None, None, 1, 0, None,
None, win32process.STARTUPINFO())
msg83522 - (view) Author: Erik Carstensen (sandberg) Date: 2009-03-13 17:07
argh, it seems that the problem is in how CreateProcess works; exactly
the same error can be provoked from C.
msg83523 - (view) Author: Erik Carstensen (sandberg) Date: 2009-03-13 18:12
I experimented further, the only way to run a .bat file whose name
contains funny characters, seems to be:

subprocess.call('""f(o.bat""', shell=True)
msg83526 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2009-03-13 18:29
Erik Sandberg wrote:
> Erik Sandberg <sandberg@virtutech.com> added the comment:
> 
> I experimented further, the only way to run a .bat file whose name
> contains funny characters, seems to be:
> 
> subprocess.call('""f(o.bat""', shell=True)

Well there's a bit of a double-whammy going on here. There's
a long-unfixed bug which doesn't quote parameters to
subprocess under Windows when shell=True:

  http://bugs.python.org/issue2304

but in fact you don't need to set shell=True to run a batch
file anyway:

import subprocess
open ("t(o.bat", "w").write ("echo we are here\n")
subprocess.call (["t(o.bat"])
msg83534 - (view) Author: Erik Carstensen (sandberg) Date: 2009-03-13 20:03
Did you test your code? I'm pretty sure I tried almost exactly the code
you suggest, and got an error like "'t' is not recognized as an internal
or external command...' (I cannot test this right now as I don't have
access to Windows machines). In order to use shell=False, I think the
correct thing should be something like this, though I haven't tried it
myself yet:
subprocess.call(["/c", "t(o.bat"], executable="cmd.exe")

(this guess is based on what I read in msdn.com's docs on CreateProcess:
"""To run a batch file, you must start the command interpreter; set
lpApplicationName to cmd.exe and set lpCommandLine to the following
arguments: /c plus the name of the batch file.""")
msg83535 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2009-03-13 20:20
Erik Sandberg wrote:
> Erik Sandberg <sandberg@virtutech.com> added the comment:
> 
> Did you test your code? 

Several times, cutting and pasting into the Python interpreter.
But I missed the fact that you were running Python 2.5

Python 2.6.1 (r261:67517, Dec  4 2008, 16:51:00) [MSC
Type "help", "copyright", "credits" or "license" for m
>>> import subprocess
>>> open ("t(o.bat", "w").write ("echo we are here\n")
>>> subprocess.call (["t(o.bat"])

c:\temp>echo we are here
we are here
0
>>>

Testing under 2.5 shows the issue you describe

However, I doubt very much whether any change would be
made to 2.5 at this point anyway: I think it's in
security-bug-fix-only  mode now. Bizarrely, I can't
see any reason why the behaviour should have changed.
Might even be the runtime it links to.

> (this guess is based on what I read in msdn.com's docs on CreateProcess:
> """To run a batch file, you must start the command interpreter; set
> lpApplicationName to cmd.exe and set lpCommandLine to the following
> arguments: /c plus the name of the batch file.""")

In fact, the shell=True code on Windows basically does:

%COMSPEC% /c args... 

for you behind the scenes. But, as my example above shows,
you don't seem to need to do that in any case.

TJG
msg98576 - (view) Author: Brian Curtin (brian.curtin) * (Python committer) Date: 2010-01-30 21:26
I'm not seeing the same thing Tim sees on 2.6, or 3.1 for that matter. Looks like this is still an issue.
msg113685 - (view) Author: Tim Golden (tim.golden) * (Python committer) Date: 2010-08-12 15:40
OK; issue2304 is now fixed and closed. But it doesn't seem to make any difference to this behaviour. I've just retested and I see on py3k the behaviour the OP saw. CreateProcess does the same thing and I couldn't even get it to work with multiply-nested quotes. So I would maintain it's not a Python issue as such.

I'm closing as won't fix and leave it to the OP to reopen if he feels there's something which could be done.
History
Date User Action Args
2022-04-11 14:56:46adminsetgithub: 49734
2010-08-12 15:40:55tim.goldensetstatus: open -> closed
messages: + msg113685

assignee: tim.golden
resolution: wont fix
stage: test needed -> resolved
2010-01-30 21:26:56brian.curtinsetpriority: normal
versions: + Python 2.6, Python 3.1, - Python 2.5
nosy: + brian.curtin

messages: + msg98576

stage: test needed
2009-03-13 20:20:03tim.goldensetmessages: + msg83535
2009-03-13 20:03:33sandbergsetmessages: + msg83534
2009-03-13 18:29:38tim.goldensetnosy: + tim.golden
messages: + msg83526
2009-03-13 18:12:28sandbergsetmessages: + msg83523
2009-03-13 17:07:33sandbergsetfiles: + parenbug.c

messages: + msg83522
2009-03-13 16:34:19sandbergsetmessages: + msg83520
2009-03-13 14:34:51sandbergsetmessages: + msg83519
2009-03-13 14:32:05sandbergcreate