views:

229

answers:

5

I'm using python right now. I have a thread that represents my entire program. I want to open another console window using os.system(xterm&) as a thread which works. The only thing is, is it possible to print to the new window while the other thread is printing to the older window?

import sys




import os

def my_fork():
    child_pid = os.fork()
    if child_pid == 0:

        function=open('SMITH747.txt','r')
        f=function.readlines()
        fd = open("output", "w")
        # Open xterm window with logs from that file
        p = subprocess.Popen(["xterm", "-e", "tail", "-f", "output"])
        # Do logging


        while(True):
            for i in range(1):
                fd.write("Hello, world!")
                time.sleep(2)

            if f==[]:
                pass
            else:
                bud=False

            fd.flush()

    else:
        function=open('SMITH747.txt','w')
        var=input('Enter ')
        if var=='q':
            function.write('yo')

if __name__ == "__main__":
    my_fork()

this is what I have right now: It works except I can't get it to read my file and terminate if f is not []. I would appreciate it so much if someone can help me debug this part. Then it will be perfect!

A: 

You could probably create a named pipe, have your new thread write to that, then spawn a new terminal that runs tail -f on the pipe.

eduffy
hi, I put my code up. Where would I attach the tail -f?
Yuki
A: 

Use subprocess.Popen() for creation of the children process. In that case you can specify PIPE and write to stdin of the children.

import subprocess
p = subprocess.Popen(["xterm"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output = p.communicate("inputmessage")[0]

Update:

Directly xterm does not received input, so here is not so direct way.

import subprocess
# Open file for output
fd = open("output", "w")
# Open xterm window with logs from that file
p = subprocess.Popen(["xterm", "-e", "tail", "-f", "output"])
# Do logging
fd.write("Hello, world!")
fd.flush()

Now you can redirect stdout descriptor to the fd, so the "print" will write output to the file. But it will be for all threads...

optio
How would I write the stdin to Pipe?I would actually like to have var=input('Enter q here: ') be printed out in the new console.
Yuki
So, the reason why I want to open a new console is so that I can var=input('Enter q here: ') in new window and wait for user to press enter thus terminating the old thread... is it possible to do it here?
Yuki
The most simple way, i see, is create separate script.This script asks user for input and sends it over some IPC to the main app. (that NamedPipe, ex.)Main app starts this script in separate terminal and receives input
optio
So, actually. I tried this. And I decided to print out the outputs in the fd.write. Question: What are the outputs being written all at once? Can they be written one by one as they go?
Yuki
Why?* is it that the outputs are being written all at once?
Yuki
If you will flush output every time you write new record, than records will appear one by one as they go.
optio
I've re edited my code in the question.
Yuki
A: 

For a unix solution:

The command tee is meant to allow output to a log file while still outputing to the console. You second term can just follow that file with tail -f on the output file.

NWCoder
hi, I put my code up. Where would I attach the tail -f?
Yuki
A: 

the reason why I want to open a new console is so that I can var=input('Enter q here: ') >in new window and wait for user to press enter thus terminating the old thread...

Simplest way i see, is helper script for asking user in separate terminal. And it is not stdin/stdout redirection hacks :)

main.py:

import os
os.mkfifo("/tmp/1234");
os.system("xterm -e python input.py &")
f = open("/tmp/1234")
print(f.read())

input.py:

var=input('Enter q here: ')
fifo = open('/tmp/1234','w')
fifo.write(str(var))
fifo.flush()
optio
I'm sorry but how would I incorporate my print loops in the main.py??
Yuki
Also, when I run it again I get an error that tmp already exist.
Yuki
Of-course it is proof of concept, you should handle creation of the pipe, and so on...
optio
A: 
import os, subprocess, time, threading

# Reads commands from fifo in separate thread.
# if kill command is received, then down continue flag.
class Killer(threading.Thread):
   def __init__ (self):
        threading.Thread.__init__(self)
        self.continueFlag = True
   def run(self):
        fd=open('ipc','r')
        command = fd.read()
        if command == "kill\n":
            self.continueFlag = False

def my_fork():

    # create fifo for reliable inter-process communications
    # TODO: check existence of fifo
    os.mkfifo('ipc')

    # Be careful with threads and fork
    child_pid = os.fork()
    if child_pid == 0:

        fd = open("output", "w")
        subprocess.Popen(["xterm", "-e", "tail", "-f", "output"])

        # Create and start killer, be careful with threads and fork
        killer = Killer()
        killer.start()

        # Perform work while continue flag is up
        while(killer.continueFlag):
            fd.write("Hello, world!\n")
            fd.flush()
            time.sleep(2)

        # need to kill subprocess with opened xterm

    else:
        # File must be fifo, otherwise race condition is possible.
        fd=open('ipc','w')
        var=input('Enter ')
        if var=='q':
            fd.write('kill\n')

if __name__ == "__main__":
    my_fork()

P.S. discussion is far away from topic, probably you should change it.

optio