Siegfried
Siegfried

Reputation: 49

subprocess.call() in windows 10 returns an error that it can't find the file

I am working on a unix script that needs some adaptations to work under windows 10. The script uses subprocess to perform file operations using DOS commands. Specifically, a statement that uses subprocess to copy a file from a directory to the current directory returns an error message. The correct DOS command is

copy "D:\tess\catalog files\TIC55234031.fts" .

However,

ref_fits_filename="D:\TESS\catalog files\TIC55234031.fts"

and

subprocess.call(['copy ', ref_fits_filename,' .'])         # copy the ref fits file to here

which aims to perform exactly the same operation, goes wrong:

Traceback (most recent call last):
  File "EBcheck.py", line 390, in 
    subprocess.call(['copy ', ref_fits_filename,' .'])         # copy the ref fits file to here
  File "C:\Users\FD-Computers\AppData\Local\Programs\Python\Python36\lib\subprocess.py", line 267, in call
    with Popen(*popenargs, **kwargs) as p:
  File "C:\Users\FD-Computers\AppData\Local\Programs\Python\Python36\lib\subprocess.py", line 709, in __init__
    restore_signals, start_new_session)
  File "C:\Users\FD-Computers\AppData\Local\Programs\Python\Python36\lib\subprocess.py", line 997, in _execute_child
    startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified

Obviously, there must be a subtle syntax error or an issue I haven't though of that causes the problem. Are there experts in Python programmming under windows 10 to clarify the issue on this forum ? The Python version used here is the recent Python 3.6.4.

Upvotes: 1

Views: 2013

Answers (2)

glucksfall
glucksfall

Reputation: 21

Apparently, this is a problem with win10 and older versions. I tested a code with win11, and it worked as it should. However, on a virtual machine with win10, it failed and that is the reason I found this question/solution and others on the internet.

Although shell = True works, it is not a good idea. To avoid shell = True, use the solution from here:

subprocess.Popen(["cmd", "/c", "dir", "c:\\Users"], stdout=subprocess.PIPE)

Upvotes: 1

Jean-François Fabre
Jean-François Fabre

Reputation: 140297

Many reasons for this:

  1. copy is a Windows shell builtin, it's not an executable. You'd have to use shell=True
  2. your subprocess.call(['copy ', ref_fits_filename,' .']) has spaces in the arguments

So you could do:

subprocess.call(['copy', ref_fits_filename,'.'],shell=True)

But the most pythonic way would be to drop all this and use shutil.copy

import shutil
shutil.copy(ref_fits_filename,".")

As a bonus, if the copy goes wrong, you get a clean python exception.

Aside: always use raw prefix when defining windows paths as literals:

ref_fits_filename = r"D:\tess\catalog files\TIC55234031.fts"

(I guess you uppercased tess to TESS to workaround the fact that \t is the tabulation char :))

Upvotes: 4

Related Questions