Run Windows commands from Python console

eryk sun eryksun at gmail.com
Sun Sep 3 11:17:30 EDT 2017


On Sun, Sep 3, 2017 at 7:56 AM,  <g.morkvenas at gmail.com> wrote:
>
> I run Python console in Windows. Can I run cmd prompt commands
> there?

Python doesn't know the first thing about CMD's "batch" language.
Also, Python's shell (i.e. REPL) is not a system administration shell
that implicitly runs external commands. You need to use the subprocess
module for that. For example:

    >>> import subprocess
    >>> subprocess.call(['icacls.exe', 'SomeFile.ext', '/grant',
'JaneDoe:(F)']).

If you need to run a CMD command, use shell=True with a command-line
string. For example:

    >>> subprocess.call('icacls SomeFile.ext /grant %USERNAME%:(F)', shell=True)

FYI, being attached to a console for standard I/O doesn't mean you're
using a "Command Prompt" that can run CMD commands.

python.exe is a character (i.e. text user interface or command-line
interface) application that creates or inherits a console
automatically. You're probably used to running python.exe from cmd.exe
and inheriting CMD's console. But you can also run python.exe directly
from Explorer, in which case it creates its own console. If Python
creates its own console, the window will be destroyed automatically
when Python exits -- unless you create child processes that are also
attached to the console and remain running.

pythonw.exe is graphical or background application, not a character
application, so it doesn't create or inherit a console automatically.
Typically IDLE runs via pythonw.exe, in which case if you want a
console you need to call WinAPI AllocConsole() or AttachConsole().
Once attached to a console, you can open "CON", "CONIN$" , or
"CONOUT$".

> What means line below:
>
> File "<stdin>", line 1
>
> I don't have any <stdin> file.

Indeed, on Windows you cannot create a file named "<stdin>". Python
uses this fake name for the code object it compiles when reading from
stdin (i.e. the file stream opened for console input).

It's not exactly smart about this, either, since whenever an exception
is raised in the REPL it will try to open this fake file multiple
times, including trying every entry in sys.path. For example, in a
typical Python 3.6 all-users installation, it will try opening the
following file paths:

    <stdin>
    <stdin>
    C:\Program Files\Python36\python36.zip\<stdin>
    C:\Program Files\Python36\python36.zip\<stdin>
    C:\Program Files\Python36\DLLs\<stdin>
    C:\Program Files\Python36\lib\<stdin>
    C:\Program Files\Python36\<stdin>
    C:\Program Files\Python36\lib\site-packages\<stdin>
    ...

Of course, all of these attempts to open "<stdin>" necessarily fail on
Windows. On Unix, however, this can actually succeed, which is kind of
funny:

    >>> open('<stdin>', 'w').write('What the !@#$%^&*?')
    18

    >>> dit
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
        What the !@#$%^&*?
    NameError: name 'dit' is not defined



More information about the Python-list mailing list