7

Необходимо вызвать командную стоку Windows, отправить команду (например ipconfig). Затем полученный результат сохранить в Notepad.

Пробовал через pywinauto/subprocess. Дальше вывода cmd экрана продвинуться не смог.

Как можно реализовать, или в каком направлении искать?

0xdb
  • 51,614
m_dig
  • 97

3 Answers3

9

Чтобы получить результат команды как строку, не обязательно cmd.exe вызывать, можно напрямую запустить дочерний процесс:

import subprocess

output = subprocess.check_output('ipconfig')

Чтобы "сохранить в notepad", просто в файл пишите результат:

from pathlib import Path

Path('~/output.txt').expanduser().write_bytes(output)

Вместо приведённого пути (сохраняет файл output.txt в домашнюю директорию пользователя), можно специфичную для программы директорию использовать (текущую рабочую директорию или путь относительно скрипта или что appdirs модуль возвращает).

Можно за один шаг: вызывать команду и сохранить её результат в файл сразу:

with Path('~/output.txt').expanduser().open('wb', 0) as file:
    subprocess.run('ipconfig', stdout=file, check=True)

См. Python - Запуск cmd.exe с аргументом, и последующим сохранением ответа в .txt файл

Чтобы сохранить вывод, используя другую кодировку (к примеру, если вы кракозябры видите), необходимо декодировать вывод программы в Unicode, а затем сохранить в кодировке, которую понимает ваше окружение:

import ctypes
import os

encoding = os.device_encoding(1) or ctypes.windll.kernel32.GetOEMCP()
text = subprocess.check_output('ipconfig', encoding=encoding)

Byte при печати вывода внешней команды.

После этого в желаемой кодировке можно сохранить. К примеру, по умолчанию используется locale.getpreferredencoding(False) кодировка:

Path('~/output.txt').expanduser().write_text(text)

вы можете в write_text() другую кодировку передать (к примеру, encoding='utf-8').

jfs
  • 52,361
  • Спасибо, все работает. Бьюсь с кодировкой вывода) – m_dig Mar 04 '18 at 10:23
  • @m_dig: поэтому необходимо декодировать вывод программы в Unicode. Я из уже приведённой ссылки на другой ответ одно из решений прямо в текущий ответ вставил. Если это не будет в вашем случае работать, то нажмите на ссылку и там ответ прочитайте. – jfs Mar 04 '18 at 10:35
6
os.system("ipconfig >some-file.txt")
Qwertiy
  • 123,725
  • А можно как-то минусы пояснить? – Qwertiy Mar 04 '18 at 11:31
  • 1
    код может вести к кракозябрам. Код запускает shell (%COMSPEC%) без необходимости: другой синтаксис и пути поиска программы — изменение пути к результату может требовать экранирования пути и прямого редактирования строки — если папка из недоверенного источника, приходится думать о shell injection. Документация рекомендует использование subprocess модуля вместо этой функции. – jfs Mar 05 '18 at 06:50
  • @jfs, про кракозябры не понял, а с остальным вроде согласен для общего случая. – Qwertiy Mar 05 '18 at 07:23
  • нажмите в моём ответе на слово кракозябры и увидете, что это такое – jfs Mar 05 '18 at 07:53
  • @jfs, где они должны возникнуть и почему? Весь вывод запускаемой программы перенаправляется в файл, соответственно полушится нормальный текстовый файл (вероятно, в кодировке 866). На каком этапе что-то должно пойти не так? – Qwertiy Mar 05 '18 at 09:21
  • что вы думаете вы увидите открыв в notepad этот файл? – jfs Mar 05 '18 at 09:38
  • @jfs, не знаю насчёт notepad'а, но NPP кодировку определит. В любом случае, это не проблема файла. К тому же, не уверен, что ipconfig выводит что-то на кириллице. – Qwertiy Mar 05 '18 at 09:58
  • у вас может и нет проблемы, а автора есть и автор именно про "сохранить в notepad" спрашивал. На Windows, ANSI cp подразумевается для Windows приложений (когда Unicode не используется), а не OEM (пережиток dos). Код автора как раз и занимается преобразованием OEM (для выбранного окружения) в ANSI (Windows code page). – jfs Mar 05 '18 at 10:08
1

Большое спасибо за помощь. Получившийся работающий код:

def ipconf_cmd():
   text = subprocess.check_output('ipconfig')
   decoded = text.decode('cp866')
   Path('~/output.txt').expanduser().write_text(decoded) 
m_dig
  • 97
  • decode здесь не нужен. Просто encoding передайте как показано в моём ответе. Жёстко не прописывайте кодировку иначе кракозябры можно получить. Какое значение для encoding на вашей машине код из моего ответа выводит? – jfs Mar 04 '18 at 21:07