ls、find 打印的是目录条目名和属性,不会读文件内容;要看内容才换 cat、head、tail。先分清对象,再选命令。
一、目录条目不等于文件内容
ls -l report.txt # 名字、权限、大小、时间——不读内容
find . -name '*.txt' # 只给路径名
cat report.txt # 这一行才把内容读出来
实测(WSL2 Ubuntu 24.04.4,coreutils 9.4):同一个文件,ls -l 只输出元信息,cat 输出内容。要看目录树得单独装 tree,这台测试机基线里没有。
二、cat:没有文件参数时它在等输入
cat 没有文件操作数时读标准输入 [1];实测 stdin 没关闭时 timeout 2 cat 被超时杀掉(退出码 124),也就是说脚本里漏写文件名会卡住而不是报错。它的输出就是读到的字节序列 [1],工具本身不做转义。
cat -n notes.txt # 给所有行编号,含空行
cat -b notes.txt # 只给非空行编号,此时 -n 被忽略
cat -A notes.txt # 等价 -vET:制表符显示 ^I,行尾显示 $
三行含空行的文本实测对照:cat -n 把空行编号成 2,cat -b 跳过空行、把 c 编号成 2;cat -A 输出 a^Ib$。POSIX 给 cat 只定义了 -u [1],上面这些显示类选项属于 GNU 扩展 [2]。
三、head 与 tail:默认 10 行,负数写法不对称
head -n 30 report.txt # 前 30 行(不写 -n 默认 10 行)
head -n -3 report.txt # GNU:除最后 3 行之外的全部内容
tail -n +11 report.txt # 从第 11 行开始
tail -c 200 report.txt # 最后 200 字节
tail -F app.log # = --follow=name --retry,轮转后仍跟上新文件
默认 10 行是两个工具共同的行为 [3][4]。差别在参数口径:POSIX 要求 head 的 -n 是正整数 [5],所以 head -n -3(除最后 3 行)是 GNU 扩展 [3];而 tail -n -3 实测就是最后 3 行,跟 tail -n 3 一样 [4]——同一个写法在两个工具里意思不同,跨平台脚本要避开。head -c(按字节)也不在 POSIX head 的选项里 [5];tail -n +K 是 coreutils 的写法 [4]。文件不足 10 行时直接给全文、不补空行(2 行文件实测输出 2 行)。日志场景记住:tail 默认按 descriptor 跟踪,文件被改名或轮转后不会看新文件,要用 --follow=name(-F 就是它加 --retry)[4];实测轮转后 --follow=name 打印了新文件里的行并提示文件名变化,默认跟踪方式停在轮转前。
四、翻页:more 能不能后退要看实现
less -N app.log # 翻页、行号,可 b 后退
more report.txt # 逐屏看,命令由终端读
“more 只能向前”是常见说法,但 POSIX 给 more 定义了后退命令,同时允许实现不支持;不支持时应报错并提示用户 [6]。util-linux 的 more(1) 手册自陈这一版非常原始,它的 b 命令只对文件、不对管道 [7]。另外 POSIX 规定输出不是终端时 more 整份拷贝输入 [6](实测三行文件走管道时全量输出,还加了文件头)。less 明确不必先读完整文件才启动 [8]。
五、二进制文件:用 strings 或 od,别直接 cat
cat 会把二进制字节原样吐进终端 [1],控制序列可能把屏幕搞乱(reset 或 clear 恢复)。
strings -n 8 firmware.bin # 只打印 8 个字符以上的可打印串
od -c firmware.bin | head # 按字节看,含转义符
od --strings firmware.bin # 默认 3 个字符起
strings 默认最小串长是 4 [9],od 的 --strings 默认是 3 [10]。实测同一份文件(一个 3 字符串、一个 6 字符串):strings 默认只输出 6 字符那一串,加 -n 3 才输出 3 字符串;od --strings 两串都列出来。顺带一条口径:less 的 -f 会抑制打开二进制文件时的警告 [8],这条在实测的小文件上没触发,按文档口径处理。
六、速查表、回滚与局限
| 现象 | 原因 | 处理 | |—|—|—| | cat 卡住不动 | 没给文件参数,在读标准输入 | Ctrl+D 结束输入,或补上文件名 | | 二进制文件满屏乱码 | cat 原样输出字节 | 用 strings 或 od | | head -n -3 在别的系统报错 | POSIX 只接受正整数 | 改成显式行数或用 sed | | tail -f 跟不到轮转后的新日志 | 默认按文件描述符跟踪 | 用 tail -F | | more 按 b 报不支持后退 | 该实现不保留已显示内容 | 换 less |
回滚与撤销:这些都是只读命令,不改文件内容;副作用是终端显示可能被控制序列影响,reset 或 clear 即可恢复。测试文件写在 /tmp/t_lv,跑完已删除。
四个常见问题:head -n 0 无输出但退出码 0(实测);文件不足默认 10 行时 head/tail 不补空行(实测);cat 读缺失文件或目录退出码都是 1(实测);POSIX 要求 more 的输入是文本文件 [6],看二进制建议换 strings/od。
状态:草稿待审。实测环境 WSL2 Ubuntu 24.04.4(kernel 6.6.114.1-microsoft-standard-WSL2)、coreutils 9.4、util-linux 2.39.3、less 590、binutils 2.42,日期 2026-10-26。已实测:head/tail 默认 10 行、head -n 0 退出码 0、head -n -3 与 tail -n -3 语义不同、tail -n +11、head -c、tail -c +、短文件不补空行、cat -n/-b/-A、cat 无参数读 stdin、缺失文件与目录退出码 1、more 走管道时整份拷贝、strings 默认串长 4、od --strings 默认 3、tail 默认跟踪与 --follow=name 在轮转后的差异。仅文档核查尚未执行:BSD/macOS 上 head/tail 的行为、POSIX more 的交互式后退命令、tree 在最小系统中的可得性。
参考资料
- [1] cat – POSIX.1-2017 technical baseline(POSIX cat 规范)
- [2] GNU Coreutils manual – cat invocation(GNU coreutils cat 手册)
- [3] GNU Coreutils manual – head invocation(GNU coreutils head 手册)
- [4] GNU Coreutils manual – tail invocation(GNU coreutils tail 手册)
- [5] head – POSIX.1-2017 technical baseline(POSIX head 规范)
- [6] more – POSIX.1-2017 technical baseline(POSIX more 规范)
- [7] more(1) – util-linux – Debian man page(more(1) 手册页)
- [8] less(1) – General Commands Manual – Debian man page(less(1) 手册页)
- [9] strings(1) – Linux manual page (GNU binutils)(strings(1) 手册页)
- [10] GNU Coreutils manual – od invocation(GNU coreutils od 手册)
文中主要命令已在 WSL Ubuntu(24.04)实测,个别条目(未装工具/安装类命令)仅核对官方文档,未实际执行。