在Linux中如何将top命令的输出保存到文件中?

48

我想将特定的' top '命令输出写入文件。我通过搜索发现可以使用以下命令来完成。

top -n 10 -b > top-output.txt

-n参数用于指定迭代次数,-b参数用于批处理模式。如果让top命令运行10次,这个方法效果很好。但是,如果我使用Ctrl-C中断了命令的运行,输出文件似乎就会变成空的。

我事先不知道迭代次数,所以需要手动中断。如何在不指定迭代次数的情况下将top的输出保存到文件中?

我正在尝试使用的命令是:

top -b | grep init > top-output.txt

我希望能够在任何时候停止它,但是它无法工作。

编辑:为了更好地解释问题,我有一个Java代码,它调用一个带有输入文件的工具。就像这个工具以文件作为输入,并运行一段时间,然后获取下一个文件等等。我有一组100,000个需要提供给该工具的文件。所以现在我正在尝试监视特定的工具(它在Linux中作为进程运行)。我无法捕获整个“top”的数据,因为该文件会过大且包含不必要的数据。如何使用top捕获该进程的系统统计信息并将其写入文件?


你需要哪些统计数据?你了解“时间”吗? - Markus Mikkolainen
我想要获取%CPU和%MEM的使用统计数据。我认为'time'命令无法帮助我获得这些数据。 - Pradep
时间将为您提供墙钟时间和处理器时间,以便您可以计算CPU%平均值。那么如何找到工具的PID并重复运行“ps”以获取该PID呢? - Markus Mikkolainen
这样做行不通,因为该工具会不断关闭并重新打开。因此每次都会有不同的PID。如果能使用工具名称进行跟踪就太好了。 - Pradep
哦,那可能行得通。我不熟悉 Linux 中的 ps 命令。当我运行 ps 命令时,只会显示“时间”,你怎么获取其他详细信息,例如 CPU 和内存使用情况?我查看了 man 手册,但貌似也没有帮助。 - Pradep
ps auxf 是我默认使用的命令。ps u 可以提供各种有用的信息。 - Markus Mikkolainen
11个回答

47

对我而言,top -b > test.txt 将会把所有top命令的输出存储到test.txt文件中,即使我使用ctrl-c停止执行该命令也不会影响结果。建议您先执行导出操作,再使用grep命令查询结果文件。


1
以这种方式,您可以使用less或tail -f跟踪文件的增长。 - Markus Mikkolainen
4
请注意,-b标记仅适用于GNU版本的top命令。这在大多数Linux系统上很好,但可能无法在基于busybox的系统或其他UNIX系统上移植。 - dmckee --- ex-moderator kitten
他使用了-b标志,所以我认为它是可用的。 - Markus Mikkolainen
1
@dmckee 好的,已经注意到了。实际上我尝试在Mac OSX中使用-b解决同样的问题,但它没有起作用。后来发现top在OSX中没有批处理模式。 - Pradep
1
我认为你的问题可能是由于grep从输出中剥离了换行符,然后缓冲区将吞噬所有输出,直到缓冲区耗尽或流结束。只是一个猜测。 - Markus Mikkolainen
显示剩余7条评论

16

使用 while 循环和 -n 1 怎么样:

while sleep 3; do 
  top -b -n1 | grep init > top-output.txt
done

我会试一下。因为上次我尝试了一个类似的循环,top在进程离开列表后停止捕获它,并且当进程回到列表时没有重新开始捕获。我会试一下并告诉你结果。 - Pradep
@Pradep,我认为它停止的原因是while会在while条件中的最后一个命令失败时停止。这就是为什么Thor使用了while :;:是一个始终成功的特殊命令。我猜你用的是while top ...; do ...; done - Aaron McDaid
1
需要追加。并且可以在处理时清除。这将只有最新的内容。如果处理完成,则很好。 - tgkprog
1
我个人不鼓励使用第一个“top”迭代,因为据我所知,它缺乏平均值的适当参考。请参见此线程 - Campa

5

看起来输出内容直到所有迭代完成之后才写入文件。你可以通过像这样添加外部循环来解决:

touch top-output.txt
while true; do
    top -b | grep init >> top-output.txt
done

至少在我的Linux机器上,它将其作为流写入标准输出,因此输出文件实时更新。 - Markus Mikkolainen
现在试一下,我意识到我错误地设置了x的初始值,导致循环永远不会被执行。 - CIGuy
我对这一切都很新。你能告诉我如何停止它的运行吗?我尝试了Ctrl-c。但在这里不起作用。 :) - Pradep
我已经编辑了一个版本,它会一直运行直到你按下Ctrl-c。 - CIGuy
仍然无法通过 Ctrl-C 关闭。不过,Ctrl-Z 可以工作。我不知道这是否是预期的行为。 - Pradep
显示剩余3条评论

3

这是我在Mac上喜欢使用的一行命令:

top -o -pid -l 1 | grep "some regexp"

欢呼。

2

正如@Thor在评论中指出的那样,你只需要确保grep不会任意缓冲,而是使用--line-buffered选项进行按行缓冲:

top -bn 10 | grep 'init' --line-buffered | tee top-output.txt

不使用grep,将top的输出重定向到文件中,包括中断在内都可以正常工作。


1

问题已解决。即使按下Ctrl+c也有效。我在想要记录Cpu%时也遇到了同样的问题。 执行此shell脚本:

#!/bin/sh
while true; do
    echo "$(top -b -n 1 | grep init)"  | tee -a top-output.log
    sleep 1
done
  • 你可以使用grep命令提取top命令中的任何内容,使用此脚本将其存储到文件中。
  • -b:批处理模式操作开始批处理模式下的top,这对于将top输出发送到其他程序或文件可能非常有用。在此模式下,top不会接受输入并运行直到您设置的迭代限制(使用-n命令行选项)或被终止为止。
  • -n number,此选项指定top在结束之前应生成的最大迭代次数或帧数。这里我使用了-n 1
  • 要获取更多详细信息,请执行man top
  • tee -a使输出可见于控制台,并将输出存储到文件中。-a选项将输出附加到文件中。
  • 在这里,我设置了1秒的间隔。您可以指定任何其他间隔。

有关-b和-n的说明来源:manpages

man top

Kruthika

个人建议不要使用top的第一个迭代,因为它缺乏平均值的参考(请参见此评论)。 - Campa
1
这是一个在反引号中使用echo的无用之举。 (http://www.iki.fi/era/unix/award.html#echo) - tripleee

1

由于控制台仍停留在CLI中,因此CTRL+C不是理想的解决方案。您可以使用以下命令将顶部输出转储到文件中:

top -n 1 -b > top-output.txt

0

将-n参数设置为1,它告诉top在退出之前将生成多少帧。

top -b -n 1 > ~/mytopview.txt

或者甚至更好

myvar=`top -b -n 1`
echo $myvar

0

如果您希望在后台运行top命令(不必担心注销/睡眠等),可以使用nohup或批处理作业或cron或screen。

使用nohup(代表:无挂断):

假设您将top命令保存在名为top-exec.sh的文件中,并具有以下内容:

 top -p <PID> -b > /tmp/top.log

您可以将顶部命令替换为您感兴趣的任何进程。 然后,您可以使用nohup执行top-exec.sh,如下所示:

$> nohup top-exec.sh &

这将把 top 命令的所有输出重定向到一个名为"top.log"的文件中。


0

我遇到了完全相同的问题...

这是我的代码行:

top -b -u myUser | grep -v Prog.sh | grep Prog > myFile.txt

它会创建myFile.txt,但当我Ctrl+C时,它是空的。因此,在启动了我的top命令后,我启动了第二个top进程。当我找到第一个top的PID(经过一些试错)并通过第二个top杀死它时,第一个top按预期写入文件。

希望这可以帮助您!


2
缺少输出的原因是中间的 grep 会被缓冲。通过像这样运行它来避免这种情况:grep --line-buffered ... - Thor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接