Поиск по блогу

пятница, 17 января 2014 г.

При вызове консольных команд Windows из Notebook iPythons вместо кириллицы крякозябы

В iPython есть великолепная возможность - вызывать системные команды прямо из ячеек. И все работает, кроме кодировки... Эти строки я пишу в браузере. Но во всех консолях iPython картина аналогичная, вот пример
In [20]:
!Where
‘Ё­в ЄбЁб ¤ ­­®© Є®¬ ­¤л:

WHERE [/R Є в «®Ј] [/Q] [/F] [/T] и Ў«®­...

ЋЇЁб ­ЁҐ:
    Ћв®Ўа ¦ Ґв а бЇ®«®¦Ґ­ЁҐ д ©«®ў, б®ўЇ ¤ ойЁе б и Ў«®­®¬ Ї®ЁбЄ .
    Џ® 㬮«з ­Ёо Ї®ЁбЄ ўлЇ®«­пҐвбп ў ⥪г饬 Є в «®ЈҐ Ё ў Є в «®Ј е,
    гЄ § ­­ле ў ЇҐаҐ¬Ґ­­®© б।л PATH.

Џ а ¬Ґвал:
    /R       ђҐЄгабЁў­л© Ї®ЁбЄ Ё ®в®Ўа ¦Ґ­ЁҐ д ©«®ў, ᮮ⢥вбвўгойЁе
             гЄ § ­­®¬г и Ў«®­г, ­ зЁ­ п б гЄ § ­­®Ј® Є в «®Ј .

    /Q       ‚®§ўа в в®«мЄ® Є®¤  ўл室  ЎҐ§ ®в®Ўа ¦Ґ­Ёп бЇЁбЄ 
             ­ ©¤Ґ­­ле д ©«®ў (вЁеЁ© ०Ё¬)

    /F       Ћв®Ўа ¦Ґ­ЁҐ ­ ©¤Ґ­­ле д ©«®ў ў Є ўлзЄ е.

    /T       Ћв®Ўа ¦Ґ­ЁҐ а §¬Ґа , ¤ вл Ё ўаҐ¬Ґ­Ё Ё§¬Ґ­Ґ­Ёп ¤«п ўбҐе
             ­ ©¤Ґ­­ле д ©«®ў.

    и Ў«®­   � Ў«®­ Ї®ЁбЄ  ¤«п ЁбЄ®¬ле д ©«®ў.
             ‚ и Ў«®­Ґ ¬®¦­® ЁбЇ®«м§®ў вм Ї®¤бв ­®ў®з­лҐ §­ ЄЁ * Ё ?.
             ’ Є¦Ґ ¬®¦­® § ¤ ў вм Є®­бвагЄжЁЁ "$ЇҐа:и Ў«®­" Ё "Їгвм:и Ў«®­",
             Ј¤Ґ "ЇҐа" ЇаҐ¤бв ў«пҐв ЇҐаҐ¬Ґ­­го б।л, Ё
             Ї®ЁбЄ ®бгйҐбвў«пҐвбп Ї® Їгвп¬, гЄ § ­­л¬ ў ЇҐаҐ¬Ґ­­®©
             б।л "ЇҐа". ќвЁ Є®­бвагЄжЁЁ ­Ґ б«Ґ¤гҐв ЁбЇ®«м§®ў вм
             б Ї а ¬Ґв஬ /R. ЏаЁ Ї®ЁбЄҐ Є и Ў«®­г в Є¦Ґ
             ¤®Ў ў«повбп а биЁаҐ­Ёп Ё§ ЇҐаҐ¬Ґ­­®© PATHEXT.

     /?      ‚лў®¤ бЇа ўЄЁ Ї® ЁбЇ®«м§®ў ­Ёо.

  ЏаЁ¬Ґз ­ЁҐ. ќв  б«г¦ҐЎ­ п Їа®Ја ¬¬  ў®§ўа й Ґв Є®¤ ®иЁЎЄЁ 0, Ґб«Ё
              Ї®ЁбЄ Ўл« гбЇҐи­л¬, 1 - Ґб«Ё ЎҐ§гбЇҐи­л¬, Ё
              2, Ґб«Ё ў®§­ЁЄ«Ё ®иЁЎЄЁ.

ЏаЁ¬Ґал:
    WHERE /?
    WHERE Ё¬п_д ©« 1 Ё¬п_??????.*
    WHERE $windir:*.* 
    WHERE /R c:\windows *.exe *.dll *.bat  
    WHERE /Q ??.??? 
    WHERE "c:\windows;c:\windows\system32:*.dll"
    WHERE /F /T *.dll 

Мои спорадические попытки нагуглить решение не дали результата. Надо разбираться, как это работает... Начнем с того, что определимся, как и где искать. Попробуем сформулировать три правила:
  1. Есть готовое решение (Эта проблема возникла не у меня перового, значит решение есть и оно универсально.)
  2. Решение простое (Я не могу найти обсуждений позднее, чем в 2009г, значит причина моего непонимания - моя безграмоность, а не баг)
  3. Искать решение с объяснением (это всегда лучше, чем просто рецепт, поскольку ликвидирует безграмотность)
Добавления по приемам поиска:
1. Переформулируем проблему в процессе.
2. Добавлять слова из найденного, например: вместо ipython, искать python chcp 65001
3. Использовать полученную информацию о программах, например: cp 866
Пишу и удивляюсь, насколько тривиальные приемы и правила, ...все равно, что напиать "вода мокрая"... Однако, вчера и позвчера я портаил часа по два на поиски "под телевизор", т.е. искал не думая... С таким глупым времяпрепровождением пора кончать... Поэтому и формулирую здесь "очевидные" правила, дабы не думать, просто тупо вспоминать...

Решение проблемы (удовлетворительное)

Решение, как и предполагадось, нашлось просто. Как только задумался о том, почему браузер показывает страницу при переключении кодировки. Сервер http://127.0.0.1:8888/ выдает ее браузеру в соответствии с его запросом (т.е., влюбой кодировке). А сам сервер где берет данные? Очевидно, открывает экземпляр консоли (cmd.exe) и обменивается данными с ней. А там кодовая страница по умолчанию Cp866. Таким образом, если поменять страницу экземпляра консоли на utf-8, то крякозябов не будет.
In [24]:
!chcp 65001
Active code page: 65001

In [26]:
!Where
The syntax of this command is:

WHERE [/R dir] [/Q] [/F] [/T] pattern...

Description:
    Displays the location of files that match the search pattern.
    By default, the search is done along the current directory and
    in the paths specified by the PATH environment variable.

Parameter List:
    /R       Recursively searches and displays the files that match the
             given pattern starting from the specified directory.

    /Q       Returns only the exit code, without displaying the list
             of matched files. (Quiet mode)

    /F       Displays the matched filename in double quotes.

    /T       Displays the file size, last modified date and time for all
             matched files.

    pattern  Specifies the search pattern for the files to match.
             Wildcards * and ? can be used in the pattern. The
             "$env:pattern" and "path:pattern" formats can also be
             specified, where "env" is an environment variable and
             the search is done in the specified paths of the "env"
             environment variable. These formats should not be used
             with /R. The search is also done by appending the
             extensions of the PATHEXT variable to the pattern.

     /?      Displays this help message.

  NOTE: The tool returns an error level of 0 if the search is
        successful, of 1 if the search is unsuccessful and
        of 2 for failures or errors.

Examples:
    WHERE /?
    WHERE myfilename1 myfile????.*
    WHERE $windir:*.* 
    WHERE /R c:\windows *.exe *.dll *.bat  
    WHERE /Q ??.??? 
    WHERE "c:\windows;c:\windows\system32:*.dll"
    WHERE /F /T *.dll 

Ну вот, на чистом аглицком языке все и написано, правда, если попадутся русские буквы, например, в названиях файлов, то при выполнении команды !dir в этих строчках выскочат крякозябы. Потому - четвертое правило: Использовать латиницу для имен файлов и папок.
Однако, я не оговорился, когда написал выше "экземпляр консоли", поскольку, ежели очень захочется русских букв, то можно открыть (другой экземпляр консоли) cmd.exe (там останется кодировка cp866) и продублировать команду "Where", а потом скопировать сюда:
In []:
C:\Users\kiss\Documents\IPython Notebooks\web\Temp_1>where
Синтаксис данной команды:

WHERE [/R каталог] [/Q] [/F] [/T] шаблон...

Описание:
    Отображает расположение файлов, совпадающих с шаблоном поиска.
    По умолчанию поиск выполняется в текущем каталоге и в каталогах,
    указанных в переменной среды PATH.

Параметры:
    /R       Рекурсивный поиск и отображение файлов, соответствующих
             указанному шаблону, начиная с указанного каталога.

    /Q       Возврат только кода выхода без отображения списка
             найденных файлов (тихий режим)

    /F       Отображение найденных файлов в кавычках.

    /T       Отображение размера, даты и времени изменения для всех
             найденных файлов.

    шаблон   Шаблон поиска для искомых файлов.
             В шаблоне можно использовать подстановочные знаки * и ?.
             Также можно задавать конструкции "$пер:шаблон" и "путь:шаблон"
             где "пер" представляет переменную среды, и
             поиск осуществляется по путям, указанным в переменной
             среды "пер". Эти конструкции не следует использовать
             с параметром /R. При поиске к шаблону также
             добавляются расширения из переменной PATHEXT.

     /?      Вывод справки по использованию.

  Примечание. Эта служебная программа возвращает код ошибки 0, если
              поиск был успешным, 1 - если безуспешным, и
              2, если возникли ошибки.

Примеры:
    WHERE /?
    WHERE имя_файла1 имя_??????.*
    WHERE $windir:*.*
    WHERE /R c:\windows *.exe *.dll *.bat
    WHERE /Q ??.???
    WHERE "c:\windows;c:\windows\system32:*.dll"
    WHERE /F /T *.dll

C:\Users\kiss\Documents\IPython Notebooks\web\Temp_1>chcp
Текущая кодовая страница: 866

Дополнение к удовлетворительному решению

Очевидно, должны быть и библиотеки Python для взаимодействия с Windows, вот только некоторые
In [1]:
import os
print "The current working directory это", os.getcwd()
The current working directory это C:\Users\kiss\Documents\IPython Notebooks\web\oboobs

In [14]:
import sys
sys.getdefaultencoding()
Out[14]:
'ascii'
Изучать их некогда. Полагаю, что надо просто не забывать, что есть вопрос о том, как настроить перекодировку кириллицы в консоли iPython... Пока просто переходим на английский
In [25]:
!chcp 
Active code page: 65001

In [7]:
# -*- coding: UTF-8 -*-
Здесь даны основные команды для работы с кодировками Windows cmd encoding change causes Python crash Здесь перечень названий всех кодировок Code Page Identifiers
А это перечень команд консоли List of Commands and Their Availability from MS-DOS through Windows 8
Есть еще одна проблема с кодировками, которую, возможно, понадобится решать при импорте текстовых файлов в notebook print Russian text from file in windows using python
Посты чуть ниже также могут вас заинтересовать

3 комментария:

  1. Для того, чтобы кириллица отображалась, нужно выбирать другую кодировку: `!chcp 1251`

    ОтветитьУдалить
  2. Сергей, спасибо огромное - у Вас самое полно описанное решение данной проблемы, что для меня, начинающего программиста на Питоне, особенно важно.

    ОтветитьУдалить