Linux 中 Tail 命令的 9 个实用示例

Linux 中 Tail 命令的 9 个实用示例

引言

我们作为 linux 用户,经常会操作那些在后台长时间运行的进程,这些进程被称作守护进程或服务。例如 secure shell (sshd)、network manager (networkd)、volume manager (lvm)、cron 等都是服务的典型例子,这样的服务还有很多。

在许多情况下,我们需要查看这些服务的日志文件来解决系统问题。但问题在于,这些服务会产生大量的日志信息,逐条查看这些日志往往既费时又费力。这时,tail 命令就派上用场了。

tail 命令是一个命令行工具,它与 head 命令类似,用于读取文件内容,并将一个或多个文件的最后 10 行显示在屏幕上。

在这篇[1]实用的教程中,我们将深入了解 tail 命令。教程结束后,Linux 命令行用户将能够熟练地运用 tail 命令。

1.在Linux中打印文件的最后10行

默认情况下,tail 命令打印给定文件的最后 10 行,如图所示。

代码语言:javascript代码运行次数:0运行复制

$ tail /var/log/secureApr  2 14:17:24 TecMint sshd[201178]: Disconnected from user tecmint 192.168.0.162 port 59774Apr  2 14:17:24 TecMint sshd[201165]: pam_unix(sshd:session): session closed for user tecmintApr  2 14:29:12 TecMint sshd[201366]: Accepted password for tecmint from 192.168.0.162 port 56378 ssh2Apr  2 14:29:12 TecMint systemd[201371]: pam_unix(systemd-user:session): session opened for user tecmint(uid=1002) by (uid=0)Apr  2 14:29:12 TecMint sshd[201366]: pam_unix(sshd:session): session opened for user tecmint(uid=1002) by (uid=0)Apr  2 14:29:12 TecMint sshd[201382]: Received disconnect from 192.168.0.162 port 56378:11: disconnected by userApr  2 14:29:12 TecMint sshd[201382]: Disconnected from user tecmint 192.168.0.162 port 56378Apr  2 14:29:12 TecMint sshd[201366]: pam_unix(sshd:session): session closed for user tecmintApr  2 15:12:55 TecMint sshd[202049]: Accepted password for root from 192.168.0.162 port 53334 ssh2Apr  2 15:12:55 TecMint sshd[202049]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)

在这里,我们可以看到上面的命令显示了 /var/log/secure 文件的最后十行。

2. 在 Linux 中打印文件的最后 N 行

在最后一个示例中,该命令打印给定文件的最后 10 行。但是,我们可以使用 -n 选项,它允许我们限制要在屏幕上打印的行数,如图所示。

代码语言:javascript代码运行次数:0运行复制

$ tail -n 3 /var/log/secureApr  2 14:29:12 TecMint sshd[201366]: pam_unix(sshd:session): session closed for user tecmintApr  2 15:12:55 TecMint sshd[202049]: Accepted password for root from 192.168.0.162 port 53334 ssh2Apr  2 15:12:55 TecMint sshd[202049]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)

在此示例中,我们可以看到该命令现在仅显示最后三行,而不是十行。

3. Linux 中忽略文件的前 N 行

在这里,我们可以使用加号 (+) 和 -n 选项,这允许我们控制给定文件的起点。

为了理解这一点,让我们使用 +5 值从第 5 行开始输出:

代码语言:javascript代码运行次数:0运行复制

$ tail -n +5 /var/log/secureApr  2 14:17:24 TecMint sshd[201178]: Disconnected from user tecmint 192.168.0.162 port 59774Apr  2 14:17:24 TecMint sshd[201165]: pam_unix(sshd:session): session closed for user tecmintApr  2 14:29:12 TecMint sshd[201366]: Accepted password for tecmint from 192.168.0.162 port 56378 ssh2Apr  2 14:29:12 TecMint systemd[201371]: pam_unix(systemd-user:session): session opened for user tecmint(uid=1002) by (uid=0)Apr  2 14:29:12 TecMint sshd[201366]: pam_unix(sshd:session): session opened for user tecmint(uid=1002) by (uid=0)Apr  2 14:29:12 TecMint sshd[201382]: Received disconnect from 192.168.0.162 port 56378:11: disconnected by userApr  2 14:29:12 TecMint sshd[201382]: Disconnected from user tecmint 192.168.0.162 port 56378Apr  2 14:29:12 TecMint sshd[201366]: pam_unix(sshd:session): session closed for user tecmintApr  2 15:12:55 TecMint sshd[202049]: Accepted password for root from 192.168.0.162 port 53334 ssh2Apr  2 15:12:55 TecMint sshd[202049]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)

4. 显示文件的最后 N 个字符

与lines类似,我们也可以使用命令使用-c选项来显示文件的最后N个字符,如下所示:

代码语言:javascript代码运行次数:0运行复制

$ tail -c 7 /var/log/secure(uid=0)

在此示例中,我们可以看到该命令显示给定文件的最后七个 ASCII 字符。

5. 删除文件的前N个字符

同样,我们可以使用加号 (+) 和 -c 选项来跳过前 N 个字符。因此,让我们使用以下命令跳过文件的第一行:

代码语言:javascript代码运行次数:0运行复制

$ tail -c +5 /var/log/secureApr  2 03:02:59 TecMint sudo[162801]: root : TTY=pts/2 ; PWD=/root ; USER=root ; COMMAND=/bin/dnf install RApr  2 03:02:59 TecMint sudo[162801]: pam_unix(sudo:session): session opened for user root(uid=0) by root(uid=0)Apr  2 03:03:02 TecMint sudo[162801]: pam_unix(sudo:session): session closed for user rootApr  2 03:11:17 TecMint groupadd[163602]: group added to /etc/group: name=avahi, GID=70Apr  2 03:11:18 TecMint groupadd[163602]: group added to /etc/gshadow: name=avahiApr  2 03:11:18 TecMint groupadd[163602]: new group: name=avahi, GID=70Apr  2 03:11:19 TecMint useradd[163610]: new user: name=avahi, UID=70, GID=70, home=/var/run/avahi-daemon, shell=/sbin/nologin, from=noneApr  2 03:13:41 TecMint groupadd[163704]: group added to /etc/group: name=colord, GID=986Apr  2 03:13:41 TecMint groupadd[163704]: group added to /etc/gshadow: name=colord

在这里,我们可以看到该命令显示了除第一行之外的所有行。

6. 在标题中显示文件名

我们可以指示 tail 命令将当前文件名显示为显示标题,这在处理多个文件时会派上用场。因此,让我们使用 -v 选项来启用显示标题:

代码语言:javascript代码运行次数:0运行复制

$ tail -n 3 -v /var/log/secure==>/var/log/secure <==Apr  2 14:29:12 TecMint sshd[201366]: pam_unix(sshd:session): session closed for user tecmintApr  2 15:12:55 TecMint sshd[202049]: Accepted password for root from 192.168.0.162 port 53334 ssh2Apr  2 15:12:55 TecMint sshd[202049]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)

在上面的输出中,==> /var/log/secure 7. 在多个文件中将文件名显示为标题

就像任何其他文件处理命令一样,我们也可以通过 tail 命令使用多个文件。在这种情况下,显示标题用于分隔文件内容。

代码语言:javascript代码运行次数:0运行复制

$ tail -n 3 -v /var/log/secure /var/log/secure-20230402==> /var/log/secure  /var/log/secure-20230402 <==Mar 31 03:50:53 TecMint groupadd[156163]: new group: name=docker, GID=987Mar 31 04:46:11 TecMint sshd[159403]: Accepted password for root from 192.168.0.162 port 46480 ssh2Mar 31 04:46:11 TecMint sshd[159403]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)

在上面的输出中,我们可以看到每个文件的显示标题。

8. 如何禁用文件中的显示标题

在前面的示例中,我们看到该命令在处理多个文件时启用显示标题。但是,我们可以使用 -q 选项抑制这种默认行为。

代码语言:javascript代码运行次数:0运行复制

$ tail -q -n 3 /var/log/secure /var/log/secure-20230402Apr  2 14:29:12 TecMint sshd[201366]: pam_unix(sshd:session): session closed for user tecmintApr  2 15:12:55 TecMint sshd[202049]: Accepted password for root from 192.168.0.162 port 53334 ssh2Apr  2 15:12:55 TecMint sshd[202049]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)Mar 31 03:50:53 TecMint groupadd[156163]: new group: name=docker, GID=987Mar 31 04:46:11 TecMint sshd[159403]: Accepted password for root from 192.168.0.162 port 46480 ssh2Mar 31 04:46:11 TecMint sshd[159403]: pam_unix(sshd:session): session opened for user root(uid=0) by (uid=0)

在这里,我们可以看到现在该命令将一个又一个地显示文件内容,并且没有任何显示头。

9. 如何观察文件的更改

到目前为止,我们看到 tail 命令在处理完所需数量的行或字符后就会退出。然而,有时我们也想查看新生成的日志。

在这种情况下,我们可以在命令中使用 -f 选项,这使我们能够实时监视文件的更改。

为了理解这一点,首先,让我们在第一个终端中执行以下命令:

代码语言:javascript代码运行次数:0运行复制

$ tail -f /var/log/messagesApr  2 15:13:28 TecMint NetworkManager[741]:   [1680462808.8441] policy: set-hostname: current hostname was changed outside NetworkManager: 'TecMint'Apr  2 15:13:28 TecMint systemd[1]: Starting Network Manager Script Dispatcher Service...Apr  2 15:13:28 TecMint systemd[1]: Started Network Manager Script Dispatcher Service.Apr  2 15:13:37 TecMint arpwatch[11001]: rename arp.dat -> arp.dat-: Operation not permittedApr  2 15:13:38 TecMint systemd[1]: NetworkManager-dispatcher.service: Deactivated successfully.Apr  2 15:13:58 TecMint systemd[1]: systemd-hostnamed.service: Deactivated successfully.Apr  2 15:18:03 TecMint systemd[1]: Starting dnf makecache...Apr  2 15:18:03 TecMint dnf[202235]: Metadata cache refreshed recently.Apr  2 15:18:03 TecMint systemd[1]: dnf-makecache.service: Deactivated successfully.Apr  2 15:18:03 TecMint systemd[1]: Finished dnf makecache.

在这里,我们可以看到该命令在显示最后十行后无限等待:

接下来,让我们打开另一个终端并将一些文本附加到numbers-2.txt 文件中:

代码语言:javascript代码运行次数:0运行复制

$ echo "View Logs in Real-Time" >> /var/log/messages

现在,我们切换到第一个终端来查看新添加的文本:

代码语言:javascript代码运行次数:0运行复制

$ tail -f /var/log/messagesApr  2 15:13:28 TecMint NetworkManager[741]:   [1680462808.8441] policy: set-hostname: current hostname was changed outside NetworkManager: 'TecMint'Apr  2 15:13:28 TecMint systemd[1]: Starting Network Manager Script Dispatcher Service...Apr  2 15:13:28 TecMint systemd[1]: Started Network Manager Script Dispatcher Service.Apr  2 15:13:37 TecMint arpwatch[11001]: rename arp.dat -> arp.dat-: Operation not permittedApr  2 15:13:38 TecMint systemd[1]: NetworkManager-dispatcher.service: Deactivated successfully.Apr  2 15:13:58 TecMint systemd[1]: systemd-hostnamed.service: Deactivated successfully.Apr  2 15:18:03 TecMint systemd[1]: Starting dnf makecache...Apr  2 15:18:03 TecMint dnf[202235]: Metadata cache refreshed recently.Apr  2 15:18:03 TecMint systemd[1]: dnf-makecache.service: Deactivated successfully.Apr  2 15:18:03 TecMint systemd[1]: Finished dnf makecache.View Logs in Real-Time

在这里,我们可以看到 tail 命令显示了新添加的文本。

Reference

[1]

Source: https://www.tecmint.com/tail-command-linux/#5_Remove_First_N_Characters_of_File

以上就是Linux 中 Tail 命令的 9 个实用示例的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/487509.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月8日 13:57:51
下一篇 2025年11月8日 13:58:23

相关推荐

  • 使用Go通道(Channels)替代互斥锁(Mutex)

    Go语言中的通道(Channels)不仅可以用于goroutine之间的通信,还能实现同步机制,从而替代互斥锁(Mutex)的功能。本文将详细介绍如何利用通道的特性,实现对共享资源的互斥访问,并通过示例代码演示其具体用法,同时探讨使用空结构体通道chan struct{}优化内存占用的方法。 在Go…

    2025年12月15日
    000
  • Go语言并发控制:使用Channel替代Mutex实现互斥

    本文将探讨如何利用Go语言中Channel的特性,实现与Mutex互斥锁相同的功能。Channel不仅可以用于goroutine之间的通信,还能提供同步机制,保证数据访问的安全性。我们将通过具体示例,展示如何使用Channel来控制对共享资源的并发访问,并讨论使用chan struct{}优化内存占…

    2025年12月15日
    000
  • Go 语言中利用接口实现切片/数组的“泛型”处理(Go 1.18前经典模式)

    本文探讨了 Go 语言在引入泛型之前,如何通过定义和实现接口来解决切片/数组缺乏协变性的问题。当需要编写可处理多种不同类型切片的通用函数时,这种接口模式提供了一种灵活且符合 Go 语言习惯的解决方案,它允许我们以统一的方式访问和操作不同类型的集合数据,有效避免了类型转换错误。 在 go 语言中,一个…

    2025年12月15日
    000
  • Go 语言泛型:从缺失到 Go 1.18 的引入与设计考量

    Go 语言在设计之初因对类型系统复杂性和运行时开销的考量,并未立即引入泛型,而是通过内置类型如 map 和 slice 以及 interface{} 提供部分通用性,但牺牲了类型安全和代码简洁性。随着语言生态的成熟和社区的呼声,Go 团队经过深思熟虑,最终在 Go 1.18 版本中正式引入了泛型,极…

    2025年12月15日
    000
  • Go 语言泛型的演进:从早期考量到 Go 1.18 的正式引入

    Go 语言在早期版本中因设计复杂性与权衡考量,并未原生支持泛型,开发者常依赖空接口(interface{})和内置类型实现通用逻辑。然而,随着语言的成熟与社区需求增长,Go 团队持续探索并最终在 Go 1.18 版本中正式引入了泛型。这一重大更新极大地提升了代码的类型安全、可重用性与表达能力,解决了…

    2025年12月15日
    000
  • Go 语言中利用接口实现切片协变性与通用操作

    本文探讨了 Go 语言中切片类型(如 []int 和 []float64)之间缺乏协变性(即 []int 不能直接赋值给 []interface{})的问题。针对此挑战,文章详细介绍了一种 Go 语言的惯用解决方案:通过定义一个通用接口来抽象集合的访问行为,并让具体类型的切片实现该接口,从而实现对不…

    2025年12月15日
    000
  • Go语言性能分析:掌握pprof工具的使用

    Go语言现在提供了强大的性能分析工具,特别是内置的pprof包。通过pprof,开发者可以对CPU、内存、Goroutine等进行详细的性能剖析,并结合可视化工具(如Google perftools)生成报告,从而定位和优化程序瓶颈。 Go语言性能分析概述 在软件开发中,性能优化是提升用户体验和系统…

    2025年12月15日
    000
  • Go语言性能剖析工具:深入理解与实践pprof

    Go语言自发布以来,性能分析工具已日趋完善。本文将深入探讨Go官方提供的pprof工具包,它是进行CPU、内存、阻塞、互斥锁和goroutine性能剖析的核心。我们将介绍pprof的基本使用方法,包括如何生成和分析性能数据,并简要提及其与Google perftools的关联,帮助开发者高效定位和优…

    2025年12月15日
    000
  • Go语言性能分析:使用pprof工具进行性能调优

    Go语言提供了强大的内置性能分析工具,主要通过pprof包实现。它允许开发者详细分析CPU、内存、Goroutine等资源的使用情况,帮助识别性能瓶颈。结合go tool pprof命令,可以生成可视化报告,从而高效地优化Go应用程序的性能。 Go语言性能分析概述 go语言自设计之初就考虑了并发和性…

    2025年12月15日
    000
  • Go语言中实现泛型切片操作:接口模式详解

    本文探讨Go语言在缺乏原生泛型和切片协变特性时,如何实现对不同类型切片进行统一处理。针对[]int无法直接作为[]interface{}传递的问题,文章详细介绍了通过定义和实现接口来模拟泛型行为的解决方案。该方法允许创建可操作任意符合特定接口的切片类型,从而提升代码的通用性和复用性,尽管相比原生泛型…

    2025年12月15日
    000
  • Go语言泛型:从设计考量到Go 1.18的引入

    Go语言在早期设计中,出于对语言简洁性和运行时复杂度的考量,并未原生支持泛型。开发者通常利用内置类型如map、slice以及空接口interface{}来实现泛型功能,但这牺牲了类型安全并增加了运行时开销。随着Go语言的不断演进,社区对泛型的呼声日益高涨,最终在Go 1.18版本中正式引入了泛型,极…

    2025年12月15日
    000
  • Go 泛型:从历史考量到 Go 1.18 的实践与应用

    Go 语言在设计之初因对类型系统复杂性和运行时开销的考量,并未直接支持泛型,而是依赖内置类型(如 map、slice)和 interface{} 来实现一定程度的通用性。然而,这种设计在处理通用数据结构和算法时带来了类型安全和代码冗余的问题。随着 Go 1.18 版本的发布,泛型正式被引入,极大地提…

    2025年12月15日
    000
  • Go Web服务器计数异常:探究与并发安全实践

    本文旨在深入探讨Go语言Web应用中可能出现的计数器异常递增问题。该问题通常并非由操作系统特性引起,而是源于浏览器自动请求favicon.ico以及Go HTTP处理器在并发环境下对共享变量操作缺乏同步机制。文章将提供详细的分析、调试方法及相应的解决方案,包括如何正确处理favicon.ico请求和…

    2025年12月15日
    000
  • Go 泛型:从缺失到引入与实践

    Go语言自诞生以来,其简洁性与高效性备受推崇,但长期以来缺乏泛型支持是其一大争议点。早期设计者权衡了类型系统复杂性与运行时开销,并提供了interface{}作为替代方案。然而,随着Go 1.18版本的发布,泛型功能正式引入,极大地提升了语言的表达能力、代码复用性和类型安全性,使得开发者能够编写更加…

    2025年12月15日
    000
  • Go语言中利用接口实现切片通用处理:弥补协变性缺失

    本文探讨了Go语言中切片缺乏协变性(即[]int不能直接赋值给[]interface{})的问题。针对此限制,文章详细介绍了一种Go语言惯用的解决方案:通过定义通用接口,并让具体切片类型实现该接口,从而实现对不同类型切片的统一处理,有效提升代码的灵用性和可维护性。 Go 语言切片协变性限制解析 在g…

    2025年12月15日
    000
  • Go语言HTTP服务器在Windows下计数异常问题排查与解决

    本文针对Go语言编写的HTTP服务器在Windows环境下出现计数异常的问题进行深入分析。通过示例代码演示了该问题,并结合浏览器的favicon请求机制,解释了计数翻倍的原因。同时,也指出了并发环境下访问共享变量的潜在风险,并提出了相应的解决方案。 问题现象 在Windows (MinGW)环境下,…

    2025年12月15日
    000
  • Go语言Web应用在Windows下计数异常问题排查与解决方案

    本文针对Go语言编写的Web应用在Windows环境下出现计数异常的问题进行了深入分析。通过示例代码展示了在Linux和Windows(MinGW)环境下计数行为的差异,并提出了浏览器自动请求favicon.ico导致重复计数以及并发访问未同步的问题,最终提供了相应的解决方案,帮助开发者避免类似问题…

    2025年12月15日
    000
  • Go test运行时提示依赖包缺失如何解决?

    go test运行时提示依赖包缺失的解决方法如下:1. 使用go mod tidy自动下载缺失依赖;2. 检查测试文件import语句是否完整正确;3. 通过go mod graph分析并解决版本冲突;4. 确认replace指令配置正确;5. 配置私有仓库访问权限;6. 手动添加隐式依赖;7. 根…

    2025年12月15日 好文分享
    000
  • Golang的bytes库为何比strings高效 分析底层切片操作优化

    bytes库在处理字符串时更高效的原因在于其操作的是可变的字节切片,避免了频繁的内存分配和拷贝。1. strings库的字符串不可变,每次修改都会创建新副本,带来性能开销;2. bytes.buffer通过原地修改字节切片实现高效追加与替换;3. bytes库直接操作底层数据,支持零拷贝和二进制处理…

    2025年12月15日 好文分享
    000
  • Golang如何优化接口调用开销 使用具体类型与编译器优化方案

    调用接口在 golang 中可能带来性能损耗,尤其在高频函数中更明显,可通过使用具体类型、利用编译器优化、减少反射和接口滥用等方式优化。首先,在性能敏感路径上尽量避免使用 interface{},改用具体类型以省去类型检查与转换开销;其次,编写小而简单的函数便于编译器进行内联优化,并通过 -m 参数…

    2025年12月15日 好文分享
    000

发表回复

登录后才能评论
关注微信