1

I can run commands in prompt from a python script but I want to save the output to a specific file. This script will pull a directory listing:

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

and write to a file where my python program was ran:

import sys
sys.stdout = open('badfile', 'w')
print('test')

However I'm trying to combine the two so that the results from the Dir command will be appended to the file "badfile" in a specified location such as C:\users\idiot\somerandomdirectory and not just the default location.

ghchoi
  • 4,812
  • 4
  • 30
  • 53
  • Then why don't you prove a specific path through the prompt? – ghchoi Feb 13 '20 at 03:23
  • Does this answer your question? [How do I pipe a subprocess call to a text file?](https://stackoverflow.com/questions/4856583/how-do-i-pipe-a-subprocess-call-to-a-text-file) – Emrah Diril Feb 13 '20 at 05:11

1 Answers1

1

Append output to a file

Q. I'm trying to combine the two so that the results from the Dir command will be appended to the file "badfile"

A. The Python answer is below this one ...

The Command Line Way ...

This can be done in python, but there are probably easier ways to achieve what you want. Here is one to consider:

The usual method is to use the Command Prompt or shell to do these things. You could still have a python script doing things, but then you run it from the command prompt and send the output somewhere else. The easiest way, the way that was designed for this exact case, is to use 'redirection.' You 'catch' the output from the program or script and send it somewhere else. This process is called 'redirection.'

This is how to do it for your example:

C:\myfolder> dir *.* >> C:\some\random\directory\badfile.txt

If you wanted to erase the file before sending your text, you would use a single > symbol instead of the >> notation.


Redirection

The general syntax for your example is:

COMMAND >> FILENAME (append COMMAND output to the end of FILENAME)

The >> symbol between the COMMAND and FILENAME is a 'redirection operator.'


A redirection operator is a special character that can be used with a command, like a Command Prompt command or DOS command, to either redirect the input to the command or the output from the command.

By default, when you execute a command, the input comes from the keyboard and the output is sent to the Command Prompt window. Command inputs and outputs are called command handles.

Here are some examples:

   command > filename        Redirect command output to a file

   command >> filename       APPEND into a file

   command < filename        Type a text file and pass the text to command

   commandA  |  commandB     Pipe the output from commandA into commandB

   commandA &  commandB      Run commandA and then run commandB

   commandA && commandB      Run commandA, if it succeeds then run commandB

   commandA || commandB      Run commandA, if it fails then run commandB

I mostly use macOS nowadays, but the ideas are similar.

Here is a cheatsheet for Windows.

Here is a cheatsheet Linux and macOS.


The Pythonic Way

As for python, do this:

import subprocess

with open('C:/temp/badfile.txt', mode='at',) as f: 
    f.write(subprocess.check_output(['dir','*.*']).decode())

There. Done. Python really is great.

To have a program that takes in any command line arguments and writes the results to sp.log, like this:

sp dir *.* /w

create a python script called sp like this:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

from subprocess import check_output
from sys import argv

if len(argv) > 1:
    with open('sp.log', mode='at',) as f:
        try:
            f.write(check_output(argv[1:]).decode())
        except Exception as e:
            print(e)

There are a lot of other things you could add, like checking default encoding, making it work with windows/macOS/linux, adding error checking, adding debugging information, adding command line options ...

Here is a GIST of a longer and more detailed version that I threw together to play with:

https://gist.github.com/skeptycal

Community
  • 1
  • 1
Michael Treanor
  • 585
  • 8
  • 9