0

The following line of python code opens a new windows cmd prompt and executes the ipconfig command but fails to redirect the output to a file I give it.

os.system("start cmd /k ipconfig > {file_name}")

If I do the same command directly into a cmd prompt, it has no problem with the redirection. Any idea why this might fail?

user3662531
  • 71
  • 1
  • 7
  • Pretty much a duplicate of [this](https://stackoverflow.com/questions/19906224/redirection-opeartors-and-in-os-systemcmd). TD;DR: use subprocess instead of os.system, as mentioned in the [docs](https://docs.python.org/2/library/os.html#os.system). – etene Apr 10 '18 at 15:00
  • 1
    @Graipher No it won't, not without a call to `format()`. The braces are interpreted literally and `{file_name}` is a valid, if idiosyncratic, filename in Windows. – BoarGules Apr 10 '18 at 23:54

1 Answers1

1

If I type this command at a command prompt

start cmd /k ipconfig > {file_name}

it doesn't redirect the output from ipconfig. It opens a new console and in that console it runs ipconfig, sending output to the screen. start produces no output of its own, so the > redirects non-existent output from start to {filename} and creates a zero-byte output file.

To do the redirection using start you need to associate the > with ipconfig like this:

start cmd /k "ipconfig > {file_name}"

But if you're planning to invoke a shell from a Python program, it's usually not handy to open a console window and leave it there. If I type this simpler command at the command prompt

ipconfig > {file_name}

it works as you describe. Likewise,

os.system(r"ipconfig > C:\users\.blah.\{file_name}")

will work in Python, but you need to specify the path of the output file, because otherwise os.system() will probably try to send the file to a default location that you're not permitted to write to (because it is a subfolder of Program Files). Use an r-string so that you don't have the hassle of doubling backslashes.

And consider using the subprocess module in preference to os.system.

BoarGules
  • 16,440
  • 2
  • 27
  • 44
  • It seems that `>` redirection does not work in every Windows shell; so I would be less assertive on the "it works as you describe" part. `subprocess` is the way to go. – etene Apr 10 '18 at 15:21
  • 1
    @etene Really, which one? I thought I had worked in all of them, going right back to 16-bit Windows 3.1. People who "discover" that redirection doesn't work in Windows are generally (and unknowingly) passing the `>` as a parameter to the executable in `ShExecInfo.lpParameters` and expecting the program to handle it. – BoarGules Apr 10 '18 at 16:15
  • Yes, that was indeed a misconception on my part, I couldn't check since I don't have a Windows machine at hand (hence the "it seems that"). Thanks for correcting me ! – etene Apr 10 '18 at 16:27
  • Of Windows shells, the strangest when it comes to redirection and piping is PowerShell. It sets itself up as a man in the middle, doing text mode decoding and encoding and LF => CRLF translation. When you want binary piping and redirection in PowerShell, the simplest answer is running `cmd.exe /c "..."`. – Eryk Sun Apr 10 '18 at 20:25
  • @eryksun PowerShell, for all that it runs under Windows, is anything but a Windows shell. Windows shells, somewhat like Unix shells, allow processes to pipe ascii streams to one another. PowerShell pipes are quite different. They pipe `.net` objects from one process to the next. If the target process is the console, you see a text representation of the object, much like what happens if you ask the Python interpreter to show you a list. PowerShell is clever and can be extraordinarily powerful, but is difficult for nonprogrammers. Which is why much of its target market still uses `.bat` files. – BoarGules Apr 10 '18 at 23:25
  • I know it's an object pipeline, but it should have an option (i.e. syntax) to set up file/pipe redirection without PowerShell as a man in the middle. – Eryk Sun Apr 10 '18 at 23:35
  • I assume when you say the target process is the "console", you mean a regular process that uses standard I/O (i.e. the `StandardInput`, `StandardOutput`, and `StandardError` handles in the PEB process parameters). Typically only console applications use standard I/O. The console itself is a subsystem that consists of csrss.exe, condrv.sys (driver for console files), and an instance of conhost.exe (hosts the window and implements much of the API). – Eryk Sun Apr 10 '18 at 23:36