Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Consistent way to redirect both stdin & stdout to files in python using optparse

I've got a dozen programs that can accept input via stdin or an option, and I'd like to implement the same features in a similar way for the output.

The optparse code looks like this:

parser.add_option('-f', '--file',
       default='-',
       help='Specifies the input file.  The default is stdin.')
parser.add_option('-o', '--output',
       default='-',
       help='Specifies the output file.  The default is stdout.')

The rest of the applicable code looks like this:

if opts.filename == '-':
    infile = sys.stdin
else:
    infile = open(opts.filename, "r")

if opts.output == '-':
    outfile = sys.stdout
else:
    outfile = open(opts.output, "w")

This code works fine and I like its simplicity - but I haven't been able to find a reference to anyone using a default value of '-' for output to indicate stdout. Is this a good consistent solution or am I overlooking something better or more expected?

like image 224
KenFar Avatar asked Oct 22 '11 22:10

KenFar


People also ask

How do I redirect stdout and stderr to the same location?

Discussion. &> or >& is a shortcut that simply sends both STDOUT and STDERR to the same place—exactly what we want to do.

What is Stdin redirection?

Input/Output (I/O) redirection in Linux refers to the ability of the Linux operating system that allows us to change the standard input ( stdin ) and standard output ( stdout ) when executing a command on the terminal. By default, the standard input device is your keyboard and the standard output device is your screen.

What is the correct command to redirect both the stdout and stderr to the same file?

Understanding the concept of redirections and file descriptors is very important when working on the command line. To redirect stderr and stdout , use the 2>&1 or &> constructs.


1 Answers

For input files you could use fileinput module. It follows common convention for input files: if no files given or filename is '-' it reads stdin, otherwise it reads from files given at a command-line.

There is no need in -f and --file options. If your program always requires an input file then it is not an option.

-o and --output is used to specify the output file name in various programs.

optparse

#!/usr/bin/env python
import fileinput
import sys
from optparse import OptionParser

parser = OptionParser()
parser.add_option('-o', '--output',
    help='Specifies the output file.  The default is stdout.')
options, files = parser.parse_args()
if options.output and options.output != '-':
   sys.stdout = open(options.output, 'w')

for line in fileinput.input(files):
    process(line)

argparse

argparse module allows you to specify explicitly files as arguments:

#!/usr/bin/env python
import fileinput
import sys
from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument('files', nargs='*', help='specify input files')
group = parser.add_mutually_exclusive_group()
group.add_argument('-o', '--output', 
    help='specify the output file.  The default is stdout')
group.add_argument('-i', '--inplace', action='store_true',
    help='modify files inplace')
args = parser.parse_args()

if args.output and args.output != '-':
   sys.stdout = open(args.output, 'w')

for line in fileinput.input(args.files, inplace=args.inplace):
    process(line)

Note: I've added --inplace option in the second example:

$ python util-argparse.py --help
usage: util-argparse.py [-h] [-o OUTPUT | -i] [files [files ...]]

positional arguments:
  files                 specify input files

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        specify the output file. The default is stdout
  -i, --inplace         modify files inplace
like image 70
jfs Avatar answered Oct 06 '22 10:10

jfs