1

Okay, So I wanted to dynamically either take input from STDIN or from a file, depending on the options given on the command line. In the end I came up with this code:

# Process command-line options
# e.g., python3 trowley_FASTAToTab -i INFILE -o OUTFILE -s
try:
    opts, args = getopt.getopt(sys.argv[1:], 'i:o:s')
except getopt.GetoptError as err:
    # Redirect STDERR to STDOUT (insures screen display)
    sys.stdout = sys.stderr
    # Print help information
    print(str(err))
    # Print usage information
    usage()
    # Exit
    sys.exit(2)

# Define our variables
inFile = ""      # File to be read, if there is one
outFile = ""     # Outfile to write to, if there is one
keepSeq = False  # Whether or not to keep the sequence
header = ""      # The header line we will mess with
sequence = ""    # The sequence were messing with

# Parse command line options
for (opt, arg) in opts:
    if opt == "-i":
        inFile = str(arg)
    elif opt == "-o":
        outFile = str(arg)
    elif opt == "-s":
        keepSeq = True

# Lets open our outfile or put the variable to stdout
if not outFile:
    outFile = sys.stdout
else:
    outFile = open(outFile, 'w')

for line in sys.stdin:
    # Do tons of stuff here
    print(tmpHeader, file=outFile)
# Maybe some cleanup here

Which has some odd behavour. If i specify an infile, but no outfile, it will read that file, do the stuff, and then output the result to the screen (what it's supposed to do).

If I leave off both the infile and the outfile (so input would be from stdin), once i press ctrl d (end of input), it just does nothing, exits the script. Same thing when I take the input from stdin and write to a file, just wont do anything.

I ended up fixing it by using:

while (1):
    line = inFile.readline()
    if not line:
        break
    # Do all my stuff here

My question is, Why wont the for line in inFile work? I get no errors, just nothing happens. Is there some unspecified rule i'm breaking?

Fooldj
  • 163
  • 1
  • 14
  • I think it is because `for line in sys.stdin` buffers stdin if you are typing at the terminal. If you type enough characters to fill the buffer, it will start processing them. If you prepare your input in a file first, and then do `cat file.txt | python myscript.py`, you will probably get better behavior. – Markku K. Jan 30 '14 at 20:56
  • Ugh. You should consider using `argparse` instead of the ancient `getopt`. – Bakuriu Jan 30 '14 at 21:00
  • Hmmm, it does work with pipes. However even with a file with just 1 sequence the pipes will work. Does the buffer problem really explain that? Would seem like the pipes are working cause it's sending a special signal, that I can't emulate from command line. – Fooldj Jan 31 '14 at 00:52
  • I can't reproduce this in 3.3 on Linux/Windows. 3.x always opens `stdin` buffered using a `BufferedReader`. `stdin.__next__` calls `stdin.readline`, which calls `stdin.buffer.read1` to get a chunk. – Eryk Sun Jan 31 '14 at 06:32
  • Even in 2.x, which uses an 8 KiB read-ahead buffer for `file.next` (not `readline`), when I press `ctrl+d` (`ctrl+z enter` in Windows) it processes the buffered lines. I don't get "nothing happens". – Eryk Sun Jan 31 '14 at 06:33
  • possible duplicate of [Turn off buffering](http://stackoverflow.com/questions/8416586/turn-off-buffering) – Apalala Jan 31 '14 at 15:38
  • and thanks @apalala but The pipes work great for me, the problem is with actually pasting the data on command line. Which i'm not sure why it's working with the pipes and not just on the pasting. – Fooldj Jan 31 '14 at 20:39
  • @eryksun - By "does nothing" i mean it drops out of the program, doesn't write any output to stdout or to a file (if i use that option) When i press control D in a linux environment Could you paste your code to me, and ill test that on my environment? Maybe there's something weird with my environ... – Fooldj Jan 31 '14 at 20:40

0 Answers0