Не удается найти файл, указанный при использовании subprocess.call('dir', shell = True) в Python

В 64-разрядной системе с установленным 32-разрядным python 2.7 я пытаюсь сделать следующее:

import subprocess
p = subprocess.call('dir', shell=True)
print p

Но это дает мне:

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    p = subprocess.call('dir', shell=True)
  File "C:\Python27\lib\subprocess.py", line 522, in call
    return Popen(*popenargs, **kwargs).wait()
  File "C:\Python27\lib\subprocess.py", line 709, in __init__
    errread, errwrite)
  File "C:\Python27\lib\subprocess.py", line 957, in _execute_child
    startupinfo)
  WindowsError: [Error 2] The system cannot find the file specified

Если я в терминале...

dir

... он, конечно, печатает содержимое текущей папки.

Я попытался изменить параметр оболочки на shell = False.

Изменить: На самом деле я не могу вызывать любой исполняемый файл на пути с помощью subprocess.call(). Оператор p = subprocess.call('dir', shell=True) отлично работает на другой машине, и я думаю, что это связано.

Если я делаю

 subprocess.call('PATH', shell=True)

то я получаю

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    subprocess.call('PATH', shell=True)
  File "C:\Python27\lib\subprocess.py", line 522, in call
     return Popen(*popenargs, **kwargs).wait()
  File "C:\Python27\lib\subprocess.py", line 709, in __init__
    errread, errwrite)
  File "C:\Python27\lib\subprocess.py", line 957, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

Если я это сделаю:

import os
print os.curdir

то я получаю

.

Все вышесказанное выполняется в терминале, запущенном в режиме администратора.

Ответы

Ответ 1

Я думаю, что у вас может быть проблема с вашей переменной среды COMSPEC:

>>> import os
>>> os.environ['COMSPEC']
'C:\\Windows\\system32\\cmd.exe'
>>> import subprocess
>>> subprocess.call('dir', shell=True)

    (normal output here)

>>> os.environ['COMSPEC'] = 'C:\\nonexistent.exe'
>>> subprocess.call('dir', shell=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\Python27\lib\subprocess.py", line 493, in call
    return Popen(*popenargs, **kwargs).wait()
  File "c:\Python27\lib\subprocess.py", line 679, in __init__
    errread, errwrite)
  File "c:\Python27\lib\subprocess.py", line 896, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

Я обнаружил эту потенциальную проблему, копаясь в subprocess.py и смотря в функции _execute_child, как указано на трассировке. Там вы найдете блок, начинающийся с if shell:, который будет искать среду для указанной переменной и использовать ее для создания аргументов, используемых для запуска процесса.

Ответ 2

Прежде чем опускать, обратите внимание, что вопрос был отредактирован после того, как я опубликовал этот ответ.

Я думаю, os.listdir более подходит для вашего случая:

>>> import os
>>> os.listdir()
['1.txt', '2.txt', '3.txt', 'DLLs', 'Doc', 'e.txt', 'include', 'Lib', 'libs', 'LICENSE.txt', 'm.txt', 'msvcr100.dll', 'NEWS.txt', 'py.exe', 'python.exe', 'python33.dll', 'pythonw.exe', 'pyw.exe', 'README.txt', 'Scripts', 't.txt', 'tcl', 'Tools']

Если вы хотите запустить его в самой командной строке и просто хотите называть его, вы можете использовать os.sytem:

os.system('dir')

Это запустит commmand, но возвращает 0, и вы не можете его сохранить.

Ответ 3

Если кто-то, кроме меня, не видит это в (3.4) docs сразу:

В Windows с оболочкой = True переменная среды COMSPEC указывает оболочка по умолчанию. Единственный раз, когда вам нужно указать shell = True на Windows - это когда команда, которую вы хотите выполнить, встроена в shell (например, dir или copy). Вам не нужна оболочка = True для запуска партии файл или консольный исполняемый файл.

Примечание. Перед использованием оболочки = True прочитайте раздел Вопросы безопасности.

Ответ 4

используйте Shell = True, это работает для меня.