2014-12-17 12 views
12

Ho scritto uno script python per monitorare lo stato di alcune risorse di rete, una pinger infinita, se lo si desidera. Fa ping per sempre gli stessi 3 nodi fino a quando non riceve un'interruzione della tastiera. Ho provato ad utilizzare tee per reindirizzare l'output del programma in un file, ma non funziona:Tee non mostra l'output o scrive su file

λ sudo ./pingster.py 

15:43:33  node1 SUCESS | node2 SUCESS | node3 SUCESS 
15:43:35  node1 SUCESS | node2 SUCESS | node3 SUCESS 
15:43:36  node1 SUCESS | node2 SUCESS | node3 SUCESS 
15:43:37  node1 SUCESS | node2 SUCESS | node3 SUCESS 
15:43:38  node1 SUCESS | node2 SUCESS | node3 SUCESS 
^CTraceback (most recent call last): 
    File "./pingster.py", line 42, in <module> 
    main() 
    File "./pingster.py", line 39, in main 
    sleep(1) 
KeyboardInterrupt 

λ sudo ./pingster.py | tee ping.log 
# wait a few seconds 
^CTraceback (most recent call last): 
    File "./pingster.py", line 42, in <module> 
    main() 
    File "./pingster.py", line 39, in main 
    sleep(1) 
KeyboardInterrupt 

λ file ping.log 
ping.log: empty 

Sto usando colorama per la mia uscita, ho pensato che forse potrebbe essere la causa del problema, ma ho provato la stampa qualcosa prima ancora che importassi colorama, e il file è ancora vuoto. Cosa sto facendo di sbagliato qui?

Edit: Ecco il file python che sto utilizzando

#!/home/nate/py-env/ping/bin/python 

from __future__ import print_function 
from datetime import datetime 
from collections import OrderedDict 
from time import sleep 

import ping 
import colorama 


def main(): 
    d = { 
     'node1': '10.0.0.51', 
     'node2': '10.0.0.50', 
     'node3': '10.0.0.52', 
    } 
    addresses = OrderedDict(sorted(d.items(), key=lambda t: t[0])) 

    colorama.init() 
    while True: 
     status = [] 
     time = datetime.now().time().strftime('%H:%M:%S') 
     print(time, end='\t') 
     for location, ip_address in addresses.items(): 
      loss, max_time, avg_time = ping.quiet_ping(ip_address, timeout=0.5) 
      if loss < 50: 
       status.append('{0} SUCESS'.format(location)) 
      else: 
       status.append(
        '{}{} FAIL{}'.format(
         colorama.Fore.RED, 
         location, 
         colorama.Fore.RESET, 
        ) 
       ) 
     print(' | '.join(status)) 
     sleep(1) 

if __name__ == '__main__': 
    main() 
+0

Come viene emesso il Pitchter? –

+0

Semplicemente usando la funzione di stampa vanilla python –

+0

Fa 'sudo ./pingster.py | cat' mostra l'uscita? –

risposta

20

Ecco un modo semplice di riprodurre il problema:

$ cat foo.py 
from time import sleep 
while True: 
    sleep(2) 
    print "hello" 

$ python foo.py 
hello 
hello  
(...) 

$ python foo.py | tee log 
(no output) 

Questo accade perché python buffer stdout quando non è un terminale. Il modo più semplice per unbuffer è quello di utilizzare python -u:

$ python -u foo.py | tee log 
hello 
hello 
(...) 

È anche possibile impostare lo shebang a #!/usr/bin/python -u (questo non funziona con env).

+0

Questo ha funzionato perfettamente, grazie! –

+2

Se non è possibile modificare l'invocazione 'python', è possibile impostare la variabile di ambiente' PYTHONUNBUFFERED' su una stringa non vuota e questo avrà lo stesso effetto. 'man python' descrive il comportamento in modo più dettagliato – dimo414