无法在python中执行终端命令(顶部)

时间:2018-04-11 05:07:00

标签: python terminal subprocess python-os

我有这个命令:

top -d 1.0 -n 1| grep Mem

当我在终端执行时,我得到:

KiB Mem : 16330216 total,  3902792 free, 10619512 used,  1807912 buff/cache
KiB Swap:  8509436 total,  4584448 free,  3924988 used.  4848204 avail Mem 

我想将此输出保存在文本文件中。 我想每隔10秒跟踪一次。

因此我尝试了:

def repeat():
   print(time.ctime())
   threading.Timer(10, repeat).start()
   f= open('ss.txt', 'w')
   top= os.system("sudo top -d 1.0 -n 1| grep Mem")
   s=str(top)
   text = f.write(s)
   print(text)

repeat()

但我只是打印 3

我希望将完整的信息存储在文本文件中。

2 个答案:

答案 0 :(得分:1)

输出( 3 )的原因是os.system()不会返回写入stdout的内容,而是返回执行命令的返回值(通常是没有打印,因此用户看不到。)

您当然希望获得stdout输出。最简单的方法是使用subprocess.run()而不是os.system()。由于其更强大的功能,通常建议使用subprocess模块,而不是os.system()

此外,可以在Python本身中过滤输出数据,而不是执行grep。这更简单,无需管道shell命令。管道shell命令需要shell=True作为subprocess.run()的参数,这可能是危险的,特别是如果运行sudo,因为它可能允许执行程序的人访问所有系统,不会被处理小心。我不认为这对你当前的程序来说是一种风险,但事情会发生变化和变化,而且突然之间就是......

因此,解决问题的方法是

import subprocess
cmd = ['sudo', 'top', '-d', '1.0', '-n', '1']
p = subprocess.run(cmd, stdout=subprocess.PIPE, universal_newlines=True)

with open('ss.txt', 'w') as f:
    for line in p.stdout.split('\n'):
        if 'Mem' in line:
            f.write(line)

不幸的是我目前不是Linux机器上的,所以我无法测试代码,这意味着可能存在小问题,但请尝试一下,让我知道它是否符合您的要求。

另请注意,subprocess.run()需要相当新版本的Python(3.5或更新版本),否则您必须依赖p = subprocess.check_output(...)p.communicate()

答案 1 :(得分:0)

试试这个

def repeat():               
   print(time.ctime())  
   threading.Timer(10, repeat).start()
   top= os.system("sudo top -d 1.0 -n 1| grep Mem > a.txt")
   with open('a.txt', 'r') as f:
       print(str(f.read()))


repeat()