Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Output to two different consoles using python

I am writing a script and I have two different kinds of output, say Op1 and Op2. I want to output Op1 to the terminal where the python process was called from while Op2 should be dumped to a different terminal instance. Can I do that?

Even if the answer is Linux-specific it's okay, I need a temporary solution.

like image 723
axolotl Avatar asked Jul 06 '16 08:07

axolotl


3 Answers

You can make the Python script write to a file, or pipe its output to a file python script.py >> output.log, then you can tail the file with -f which makes it continuously update the view on your console.

Example snippet

# logmaker.py
import time
import datetime

buffer_size = 0 # This makes it so changes appear without buffering
with open('output.log', 'a', buffer_size) as f:
    while(True):
        f.write('{}\n'.format(datetime.datetime.now()))
        time.sleep(1)

Run that file

python logmaker.py

Then in one or more consoles do

tail -f output.log

or less if you prefer

less +F output.log

You should get a continuous update like this

2016-07-06 10:52:44.997416
2016-07-06 10:52:45.998544
2016-07-06 10:52:46.999697
like image 101
bakkal Avatar answered Nov 04 '22 12:11

bakkal


Here are some common solutions in Linux.

To achieve this, you usually need two programs.

File i/o + Loop:

  1. main program + file writer (print Op1 and write Op2 into file A)
  2. file reader (keep fetching A file until it be modified and print the content of file A)

Socket (pipe):

  1. main program + sender (print Op1 and send Op2 to a specific socket)
  2. receiver (listen a specific socket and print Op2 while receiving things)

File i/o + Signal:

  1. main program + file writer + signal sender (print Op1 and write Op2 into file A and send signal to the daemon receiver)
  2. signal receiver (halt until receiving signal and print the content of file A)

By the way, I suppose that your requirement does not need to write any daemon program because you have certainly two consoles.

Additionally, I am pretty sure that printing on specific console is achievable.


Example of second solution [Socket]

# print1.py (your main program)
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
sock.connect(('localhost', 8001))  
Op1 = 'Op1'
Op2 = 'Op2'
print Op1 
sock.send(Op2)  
sock.close()

Steps

// a. console 2: listen 8001 port
// Luckily, nc(netcat) is enough to finish this without writing any code.
$ nc -l 8001

// b. console 1: run your main program
$ python print1.py
Op1

// c. console 2
Op2
like image 21
Kir Chou Avatar answered Nov 04 '22 10:11

Kir Chou


Following up on Kir's response above, as I am working on something similar, I further modified the script using threading so that the console listening is launched directly from the script, rather than having to be launched by hand. Hope it helps.

import subprocess
import threading
import socket
import time

def listenproc():
 monitorshell = subprocess.Popen("mate-terminal --command=\"nc -l 8001\"",shell=True)

def printproc():
 print("Local message")
 time.sleep(5) # delay sending of message making sure port is listening
 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 sock.connect(('localhost', 8001))
 sock.send("Sent message")
 time.sleep(5)
 sock.close()

listenthread = threading.Thread(name="Listen", target=listenproc, args=())
printhread = threading.Thread(name="Print", target=printproc, args=())

listenthread.start()
printhread.start()
listenthread.join()
printhread.join()
like image 25
osbornere Avatar answered Nov 04 '22 11:11

osbornere