ls 命令详解与参数实测(Ubuntu 22.04)
ls 命令逐参数实测详解:-l 七段输出解读与七种文件类型、-a/-A 隐藏条目、-h 人类可读大小、-t/-r/-S 排序、-1/-d/-i/-F/-R、--color 三模式与退出码,全部命令与回显在 Ubuntu 22.04(GNU coreutils 8.32)实测通过。
ls 命令详解与参数实测(Ubuntu 22.04)
目标:全面掌握 GNU ls 的核心参数——
-l七段长格式逐段解读与七种文件类型、-a/-A隐藏条目、-h人类可读大小、-t/-r/-S排序、-1单列、-d、-i、-F、-R、--color与退出码,全部命令与回显已在 Ubuntu 22.04(GNU coreutils 8.32)实测通过。
一、环境信息
本节记录实测环境与演示数据。ls 是文件管理使用频率最高的命令,实测特意构造了含隐藏文件、硬链接、软链接、命名管道、可执行文件、不同时间戳与大小的混合目录,保证每个参数都有可观察的现象。
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- ls 版本:GNU coreutils 8.32(
ls --version实测) - ls 属于 coreutils 基础工具集,Ubuntu 22.04 默认预装,无需额外安装
- 演示目录:
/root/demo/ls/ - 测试数据:普通文本、2KB/150B 二进制、隐藏文件、硬链接对、软链接、命名管道、可执行文件、两个指定历史时间戳的文件,以及 dir1(含子目录)、dir2(空)、empty(空)三个目录
二、命令概览
2.1 语法与测试数据准备
ls 的基本语法是 ls [OPTION]... [FILE]...:不跟 FILE 时列出当前目录(本节实测统一显式传演示目录),跟 FILE 时按指定条目列出;不指定任何排序类参数(-cftuvSUX 与 --sort)时按名称字母序排列。
先构造一套覆盖"七类文件形态中可在常规目录里出现的大多数"的演示数据:
mkdir -p /root/demo/ls/dir1/sub /root/demo/ls/dir2 /root/demo/ls/empty
echo 'alpha' > /root/demo/ls/alpha.txt
ln /root/demo/ls/alpha.txt /root/demo/ls/alpha-hard.txt
head -c 2048 /dev/zero > /root/demo/ls/big.bin
head -c 150 /dev/zero > /root/demo/ls/med.bin
echo hidden > /root/demo/ls/.hidden
echo inner > /root/demo/ls/dir1/inner.txt
echo deep > /root/demo/ls/dir1/sub/deep.txt
touch -d '2025-01-01 08:30:00' /root/demo/ls/old.txt
touch -d '2024-06-01 12:00:00' /root/demo/ls/older.txt
ln -s alpha.txt /root/demo/ls/link-alpha
mkfifo /root/demo/ls/pipe.fifo
cp /bin/true /root/demo/ls/run
chmod +x /root/demo/ls/run
验证数据就绪(长格式视图,后面 3.2 逐段解读它):
$ ls -l /root/demo/ls
total 56
-rw-r--r-- 2 root root 6 Oct 15 06:10 alpha-hard.txt
-rw-r--r-- 2 root root 6 Oct 15 06:10 alpha.txt
-rw-r--r-- 1 root root 2048 Oct 15 06:10 big.bin
drwxr-xr-x 3 root root 4096 Oct 15 06:10 dir1
drwxr-xr-x 2 root root 4096 Oct 15 06:10 dir2
drwxr-xr-x 2 root root 4096 Oct 15 06:10 empty
lrwxrwxrwx 1 root root 9 Oct 15 06:10 link-alpha -> alpha.txt
-rw-r--r-- 1 root root 150 Oct 15 06:10 med.bin
-rw-r--r-- 1 root root 0 Jan 1 2025 old.txt
-rw-r--r-- 1 root root 0 Jun 1 2024 older.txt
prw-r--r-- 1 root root 0 Oct 15 06:10 pipe.fifo
-rwxr-xr-x 1 root root 26936 Oct 15 06:10 run
注意两个细节:alpha.txt 与 alpha-hard.txt 链接数都是 2(互为硬链接);old.txt、older.txt 的时间列显示的是完整年份 Jan 1 2025、Jun 1 2024——距当前超过半年的历史时间会从"月 日 时:分"切换为"月 日 年"格式。
2.2 --help 全量回显
ls --help 的完整输出如下(实测原样保留,约 70 余个参数可作速查表使用):
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
Mandatory arguments to long options are mandatory for short options too.
-a, --all do not ignore entries starting with .
-A, --almost-all do not list implied . and ..
--author with -l, print the author of each file
-b, --escape print C-style escapes for nongraphic characters
--block-size=SIZE with -l, scale sizes by SIZE when printing them;
e.g., '--block-size=M'; see SIZE format below
-B, --ignore-backups do not list implied entries ending with ~
-c with -lt: sort by, and show, ctime (time of last
modification of file status information);
with -l: show ctime and sort by name;
otherwise: sort by ctime, newest first
-C list entries by columns
--color[=WHEN] colorize the output; WHEN can be 'always' (default
if omitted), 'auto', or 'never'; more info below
-d, --directory list directories themselves, not their contents
-D, --dired generate output designed for Emacs' dired mode
-f do not sort, enable -aU, disable -ls --color
-F, --classify append indicator (one of */=>@|) to entries
--file-type likewise, except do not append '*'
--format=WORD across -x, commas -m, horizontal -x, long -l,
single-column -1, verbose -l, vertical -C
--full-time like -l --time-style=full-iso
-g like -l, but do not list owner
--group-directories-first
group directories before files;
can be augmented with a --sort option, but any
use of --sort=none (-U) disables grouping
-G, --no-group in a long listing, don't print group names
-h, --human-readable with -l and -s, print sizes like 1K 234M 2G etc.
--si likewise, but use powers of 1000 not 1024
-H, --dereference-command-line
follow symbolic links listed on the command line
--dereference-command-line-symlink-to-dir
follow each command line symbolic link
that points to a directory
--hide=PATTERN do not list implied entries matching shell PATTERN
(overridden by -a or -A)
--hyperlink[=WHEN] hyperlink file names; WHEN can be 'always'
(default if omitted), 'auto', or 'never'
--indicator-style=WORD append indicator with style WORD to entry names:
none (default), slash (-p),
file-type (--file-type), classify (-F)
-i, --inode print the index number of each file
-I, --ignore=PATTERN do not list implied entries matching shell PATTERN
-k, --kibibytes default to 1024-byte blocks for disk usage;
used only with -s and per directory totals
-l use a long listing format
-L, --dereference when showing file information for a symbolic
link, show information for the file the link
references rather than for the link itself
-m fill width with a comma separated list of entries
-n, --numeric-uid-gid like -l, but list numeric user and group IDs
-N, --literal print entry names without quoting
-o like -l, but do not list group information
-p, --indicator-style=slash
append / indicator to directories
-q, --hide-control-chars print ? instead of nongraphic characters
--show-control-chars show nongraphic characters as-is (the default,
unless program is 'ls' and output is a terminal)
-Q, --quote-name enclose entry names in double quotes
--quoting-style=WORD use quoting style WORD for entry names:
literal, locale, shell, shell-always,
shell-escape, shell-escape-always, c, escape
(overrides QUOTING_STYLE environment variable)
-r, --reverse reverse order while sorting
-R, --recursive list subdirectories recursively
-s, --size print the allocated size of each file, in blocks
-S sort by file size, largest first
--sort=WORD sort by WORD instead of name: none (-U), size (-S),
time (-t), version (-v), extension (-X)
--time=WORD change the default of using modification times;
access time (-u): atime, access, use;
change time (-c): ctime, status;
birth time: birth, creation;
with -l, WORD determines which time to show;
with --sort=time, sort by WORD (newest first)
--time-style=TIME_STYLE time/date format with -l; see TIME_STYLE below
-t sort by time, newest first; see --time
-T, --tabsize=COLS assume tab stops at each COLS instead of 8
-u with -lt: sort by, and show, access time;
with -l: show access time and sort by name;
otherwise: sort by access time, newest first
-U do not sort; list entries in directory order
-v natural sort of (version) numbers within text
-w, --width=COLS set output width to COLS. 0 means no limit
-x list entries by lines instead of by columns
-X sort alphabetically by entry extension
-Z, --context print any security context of each file
-1 list one file per line. Avoid '\n' with -q or -b
--help display this help and exit
--version output version information and exit
The SIZE argument is an integer and optional unit (example: 10K is 10*1024).
Units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers of 1000).
Binary prefixes can be used, too: KiB=K, MiB=M, and so on.
The TIME_STYLE argument can be full-iso, long-iso, iso, locale, or +FORMAT.
FORMAT is interpreted like in date(1). If FORMAT is FORMAT1<newline>FORMAT2,
then FORMAT1 applies to non-recent files and FORMAT2 to recent files.
TIME_STYLE prefixed with 'posix-' takes effect only outside the POSIX locale.
Also the TIME_STYLE environment variable sets the default style to use.
Using color to distinguish file types is disabled both by default and
with --color=never. With --color=auto, ls emits color codes only when
standard output is connected to a terminal. The LS_COLORS environment
variable can change the settings. Use the dircolors command to set it.
Exit status:
0 if OK,
1 if minor problems (e.g., cannot access subdirectory),
2 if serious trouble (e.g., cannot access command-line argument).
GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Report any translation bugs to <https://translationproject.org/team/>
Full documentation <https://www.gnu.org/software/coreutils/ls>
or available locally via: info '(coreutils) ls invocation'
💡 说明:参数虽多,日常高频的是本文第三节实测的十几个:
-l -a -A -h -t -r -S -1 -d -i -F -R --color。帮助末尾的 Exit status 一节是排查脚本错误时的重要依据(0 正常 / 1 次要问题 / 2 严重问题),3.15 有实测。
2.3 版本确认
$ ls --version | head -1
ls (GNU coreutils) 8.32
三、参数逐项实测
3.1 无参数:按名称排序列出
不带参数,ls 按名称字母序列出目录条目(隐藏文件不显示):
$ ls /root/demo/ls
alpha-hard.txt
alpha.txt
big.bin
dir1
dir2
empty
link-alpha
med.bin
old.txt
older.txt
pipe.fifo
run
共 12 个条目,目录(dir1、dir2、empty)与文件混排在一起按名称排序——ls 默认并不"目录在前";排序的字母序基于条目名本身,.hidden 这类以点开头的隐藏条目被隐去。需要目录/文件分组显示时可用 --group-directories-first(见 2.2 帮助)。
💡 提示:帮助原文 "Sort entries alphabetically if none of -cftuvSUX nor --sort is specified." 说明只要带上任一排序参数,默认字母序即让位。
3.2 -l:长格式与七段解读
-l 是信息量最大的参数,每行输出一个条目的完整属性:
$ ls -l /root/demo/ls
total 56
-rw-r--r-- 2 root root 6 Oct 15 06:10 alpha-hard.txt
-rw-r--r-- 2 root root 6 Oct 15 06:10 alpha.txt
-rw-r--r-- 1 root root 2048 Oct 15 06:10 big.bin
drwxr-xr-x 3 root root 4096 Oct 15 06:10 dir1
drwxr-xr-x 2 root root 4096 Oct 15 06:10 dir2
drwxr-xr-x 2 root root 4096 Oct 15 06:10 empty
lrwxrwxrwx 1 root root 9 Oct 15 06:10 link-alpha -> alpha.txt
-rw-r--r-- 1 root root 150 Oct 15 06:10 med.bin
-rw-r--r-- 1 root root 0 Jan 1 2025 old.txt
-rw-r--r-- 1 root root 0 Jun 1 2024 older.txt
prw-r--r-- 1 root root 0 Oct 15 06:10 pipe.fifo
-rwxr-xr-x 1 root root 26936 Oct 15 06:10 run
以第一行 -rw-r--r-- 2 root root 6 Oct 15 06:10 alpha-hard.txt 为例,七段逐一解读:
- 类型与权限(
-rw-r--r--):首字符是文件类型,后 9 位三三一组,分别是属主、属组、其他人的 rwx 权限; - 硬链接数(
2):指向该 i-node 的目录项数量,普通文件通常为 1,目录至少为 2(自身.+ 父目录中的一项); - 属主(
root); - 属组(
root); - 大小(
6):普通文件为字节数;目录固定显示 4096(目录项表的大小,不是目录内容的累计大小);软链显示目标路径的长度(link-alpha为 9,即alpha.txt的长度); - 最后修改时间(
Oct 15 06:10):六个月内显示"月 日 时:分",更早显示"月 日 年"(如 old.txt 的Jan 1 2025); - 名称(
alpha-hard.txt);软链会附加-> 目标。
首行 total 56 是目录下所有条目按 1K 块计的磁盘占用合计(与第 5 段的文件字节数不是一回事)。
文件类型符号:七段首字符共有七种取值,结合本环境实测整理如下——
💡 技术拓展:Linux 文件系统把万物皆文件落实到七种类型,
ls -l首字符与ls -F标记一一对应——
首字符 类型 本环境实测示例 典型出处 -普通文件 -rw-r--r-- alpha.txt、-rwxr-xr-x run文本、二进制、压缩包 d目录 drwxr-xr-x dir1文件夹 l符号链接 lrwxrwxrwx link-alpha -> alpha.txtln -s创建c字符设备 crw-rw-rw- 1, 3 /dev/null终端、/dev 下多数设备 b块设备 本演示目录未采集 磁盘与分区(如 /dev/vda1) s套接字 本演示目录未采集 本地进程通信(/run 下服务的 .sock) p命名管道 prw-r--r-- pipe.fifomkfifo创建日常目录里最常见的是
-、d、l三种;c/b集中在 /dev,s多在 /run,p可用 mkfifo 自造。排查设备文件权限时,第 5 段位置显示的不再是字节数而是"主设备号, 次设备号"。
用硬链接对与设备文件验证两个特殊七段值:
$ ls -l /root/demo/ls/alpha.txt /root/demo/ls/alpha-hard.txt
-rw-r--r-- 2 root root 6 Oct 15 06:10 /root/demo/ls/alpha-hard.txt
-rw-r--r-- 2 root root 6 Oct 15 06:10 /root/demo/ls/alpha.txt
$ ls -l /dev/null
crw-rw-rw- 1 root root 1, 3 Oct 15 05:20 /dev/null
两个互为硬链接的文件链接数都显示 2(同一个 i-node 的两个名字,与 3.11 的 inode 实测互相印证);/dev/null 第 5 段是 1, 3 即主设备号 1、次设备号 3,这是设备文件独有的显示形态。
时间列默认格式较窄,排查问题时建议换 ISO 格式,年月日时分一目了然:
$ ls -l --time-style=long-iso /root/demo/ls/alpha.txt /root/demo/ls/old.txt
-rw-r--r-- 2 root root 6 2026-10-15 06:10 /root/demo/ls/alpha.txt
-rw-r--r-- 1 root root 0 2025-01-01 08:30 /root/demo/ls/old.txt
💡 提示:目录大小恒为 4096 并不代表"空目录占 4K、内容也算在里面",它是目录条目表自身的大小;统计目录总内容大小用 du。
3.3 -a:显示全部条目(含 . 与 ..)
-a(--all)在普通条目之外补上以点开头的隐藏条目,以及每个目录都有的 . 与 ..:
$ ls -a /root/demo/ls
.
..
.hidden
alpha-hard.txt
alpha.txt
big.bin
dir1
dir2
empty
link-alpha
med.bin
old.txt
older.txt
pipe.fifo
run
对比 3.1 的输出,多出的正是 .hidden 与 .、.. 两项——前者是准备数据时创建的隐藏文件,后者分别是"当前目录"与"上级目录"的目录项。
💡 提示:
ls -a 目录 | wc -l与ls -A 目录 | wc -l相差 2,差的就是.与..。
3.4 -A:几乎全部(省略 . 与 ..)
-A(--almost-all)同样显示隐藏条目,但不再输出 . 与 ..:
$ ls -A /root/demo/ls
.hidden
alpha-hard.txt
alpha.txt
big.bin
dir1
dir2
empty
link-alpha
med.bin
old.txt
older.txt
pipe.fifo
run
比 -a 少了头两行,其余完全一致。写脚本统计/遍历目录内容时用 -A 更干净,避免 .、.. 混进结果造成自引用。
💡 提示:
-A仍会显示.hidden。"隐藏"在 Linux 里只是"名字以点开头",并非权限层面的隔离。
3.5 -h:人类可读大小(配合 -l)
-h(--human-readable)把第 5 段的字节数换成 K/M/G 后缀。先用字节数视图做基准:
$ ls -l /root/demo/ls/big.bin /root/demo/ls/med.bin
-rw-r--r-- 1 root root 2048 Oct 15 06:10 /root/demo/ls/big.bin
-rw-r--r-- 1 root root 150 Oct 15 06:10 /root/demo/ls/med.bin
$ ls -lh /root/demo/ls/big.bin /root/demo/ls/med.bin
-rw-r--r-- 1 root root 2.0K Oct 15 06:10 /root/demo/ls/big.bin
-rw-r--r-- 1 root root 150 Oct 15 06:10 /root/demo/ls/med.bin
2048 字节显示为 2.0K;不足 1K 的 150 字节保持原样——ls 不会凑成 0.1K。加 -h 后列宽对齐略变宽,脚本里做数值比较时仍应取原始字节(或 --block-size=1)。
-h 也作用于目录与 total 行:
$ ls -lh /root/demo/ls/dir1
total 8.0K
-rw-r--r-- 1 root root 6 Oct 15 06:10 inner.txt
drwxr-xr-x 2 root root 4.0K Oct 15 06:10 sub
💡 提示:
-h以 1024 为进制;想要 1000 进制(与硬盘厂商标称一致)改用--si,两种口径的数值会有细微差别。
3.6 -t:按修改时间排序(新在前)
-t 按最后修改时间从新到旧排序,配合 -l 可看时间列:
$ ls -lt /root/demo/ls | head -6
total 56
-rwxr-xr-x 1 root root 26936 Oct 15 06:10 run
prw-r--r-- 1 root root 0 Oct 15 06:10 pipe.fifo
lrwxrwxrwx 1 root root 9 Oct 15 06:10 link-alpha -> alpha.txt
drwxr-xr-x 3 root root 4096 Oct 15 06:10 dir1
-rw-r--r-- 1 root root 150 Oct 15 06:10 med.bin
同一秒内创建的条目按名称稳定排序,run、pipe.fifo、link-alpha 依次排前;old.txt、older.txt 两个历史时间戳文件被排到了尾部(head -6 之外)。
💡 提示:
-t依据 mtime(内容修改时间);要按 inode 状态变更时间用-c、按访问时间用-u(见 2.2 帮助 --time 段)。
3.7 -r:逆序输出
-r(--reverse)反转任何排序的结果,最经典的组合是 -ltr:最旧的文件排最前:
$ ls -ltr /root/demo/ls | head -6
total 56
-rw-r--r-- 1 root root 0 Jun 1 2024 older.txt
-rw-r--r-- 1 root root 0 Jan 1 2025 old.txt
drwxr-xr-x 2 root root 4096 Oct 15 06:10 empty
drwxr-xr-x 2 root root 4096 Oct 15 06:10 dir2
-rw-r--r-- 2 root root 6 Oct 15 06:10 alpha.txt
2024 年的 older.txt、2025 年的 old.txt 依次排前,正是 3.6 中被排到尾部的两个文件。"找目录里最早/最新的文件"这两个高频需求分别对应 -ltr 与 -lt 加 head/tail。
💡 提示:
-r是纯粹的顺序反转器,对-S(大小排序)同样生效,见 3.8。
3.8 -S:按大小排序(大在前)
-S 按文件大小从大到小排序:
$ ls -lS /root/demo/ls
total 56
-rwxr-xr-x 1 root root 26936 Oct 15 06:10 run
drwxr-xr-x 3 root root 4096 Oct 15 06:10 dir1
drwxr-xr-x 2 root root 4096 Oct 15 06:10 dir2
drwxr-xr-x 2 root root 4096 Oct 15 06:10 empty
-rw-r--r-- 1 root root 2048 Oct 15 06:10 big.bin
-rw-r--r-- 1 root root 150 Oct 15 06:10 med.bin
lrwxrwxrwx 1 root root 9 Oct 15 06:10 link-alpha -> alpha.txt
-rw-r--r-- 2 root root 6 Oct 15 06:10 alpha-hard.txt
-rw-r--r-- 2 root root 6 Oct 15 06:10 alpha.txt
-rw-r--r-- 1 root root 0 Jan 1 2025 old.txt
-rw-r--r-- 1 root root 0 Jun 1 2024 older.txt
prw-r--r-- 1 root root 0 Oct 15 06:10 pipe.fifo
注意排序依据是第 5 段:目录按 4096 参与排序(dir1/dir2/empty 并列时按名称稳定序),软链按目标名长度 9,普通文件按字节数;0 字节的 old.txt、older.txt、pipe.fifo 排在最后。加 -r 立即反转为从小到大:
$ ls -lSr /root/demo/ls | head -8
total 56
prw-r--r-- 1 root root 0 Oct 15 06:10 pipe.fifo
-rw-r--r-- 1 root root 0 Jun 1 2024 older.txt
-rw-r--r-- 1 root root 0 Jan 1 2025 old.txt
-rw-r--r-- 2 root root 6 Oct 15 06:10 alpha.txt
-rw-r--r-- 2 root root 6 Oct 15 06:10 alpha-hard.txt
lrwxrwxrwx 1 root root 9 Oct 15 06:10 link-alpha -> alpha.txt
-rw-r--r-- 1 root root 150 Oct 15 06:10 med.bin
💡 提示:
-S不递归——它只排当前一层;要找整棵目录树里最大的文件,配合du -a | sort -nr或 find 的-size。
3.9 -1:单列输出
-1 强制每行一个条目。向终端输出时 ls 本就单列,真正的差别在管道与空目录场景。先看空目录——无参数时输出为空:
$ ls /root/demo/ls/dir2
$ ls -1 /root/demo/ls/dir1
inner.txt
sub
dir2 是空目录,两种写法都零输出;非空目录下 -1 保证逐行一个名字,是 ls | wc -l、ls | xargs 这类管道组合最稳妥的写法(终端列宽变化不影响解析)。
💡 提示:脚本里更推荐
ls -1(或find -maxdepth 1)而不是裸ls:裸 ls 在输出到终端时是多列布局,重定向/管道时才自动变单列,行为依赖环境。
3.10 -d:只列目录本身
目录作为参数传给 ls 时,默认会展开列出其内容;-d(--directory)让 ls 把目录当普通条目对待,只显示目录自身属性:
$ ls -ld /root/demo/ls/dir1
drwxr-xr-x 3 root root 4096 Oct 15 06:10 /root/demo/ls/dir1
$ ls -d /root/demo/ls/*/
/root/demo/ls/dir1/
/root/demo/ls/dir2/
/root/demo/ls/empty/
$ ls /root/demo/ls/dir1; echo ---; ls -d /root/demo/ls/dir1
inner.txt
sub
---
/root/demo/ls/dir1
第三条对照最直观:不带 -d 列出的是 dir1 里的 inner.txt 与 sub;带 -d 只给目录本身一行。ls -d */ 借助 shell 通配符 */(只匹配目录)是"只列子目录名"的经典组合。
💡 提示:想知道"某个目录自身的权限/属主/时间",
ls -ld 目录是标准答案,替代进入目录后再ls -l .的绕路写法。
3.11 -i:inode 与硬链接确认
-i 在每个条目前多显示一列 i-node 号。对硬链接对实测——两个名字、同一个 inode:
$ ls -i /root/demo/ls/alpha.txt /root/demo/ls/alpha-hard.txt
31614560 /root/demo/ls/alpha-hard.txt
31614560 /root/demo/ls/alpha.txt
$ ls -li /root/demo/ls/alpha.txt
31614560 -rw-r--r-- 2 root root 6 Oct 15 06:10 /root/demo/ls/alpha.txt
两个路径的 inode 同为 31614560,证实 alpha.txt 与 alpha-hard.txt 是同一份数据的两个目录项(对应 3.2 中链接数 2)。-li 组合把 inode 列并入长格式。
💡 提示:inode 号是文件在文件系统层面的身份,
find -inum反查、df -i看总量都基于它;判断"是不是硬链接对"比看链接数更直接。
3.12 -F:类型标记符号
-F(--classify)在每个条目尾部追加类型标记,不用颜色也能一眼分辨类型:
$ ls -F /root/demo/ls
alpha-hard.txt
alpha.txt
big.bin
dir1/
dir2/
empty/
link-alpha@
med.bin
old.txt
older.txt
pipe.fifo|
run*
$ ls -F /root/demo/ls/run /root/demo/ls/pipe.fifo /root/demo/ls/link-alpha
/root/demo/ls/link-alpha@
/root/demo/ls/pipe.fifo|
/root/demo/ls/run*
标记规则与 3.2 的七类一一对应:目录 /、符号链接 @、命名管道 |、可执行文件 *;普通文件(含 .hidden)无标记。=(socket)与 >(door)在常规目录中少见。第二组实测确认单文件形态下标记同样生效。
💡 提示:
-F输出的标记是 ls 附加的显示字符。管道下游若要把标记当文件名用会出错,此类场景改用-p(只有目录加/)或干脆去掉 -F。
3.13 -R:递归列出子目录
-R 递归展开每个子目录,每个目录的内容以"目录名:+列表+空行"分节显示:
$ ls -R /root/demo/ls/dir1
/root/demo/ls/dir1:
inner.txt
sub
/root/demo/ls/dir1/sub:
deep.txt
dir1 下的 inner.txt 与 sub 被列出后,sub 又作为新的一节展开出 deep.txt。目录层级深时输出会很长,大目录树建议用 tree -L 2 控制深度。
💡 提示:
-R与-l组合(ls -lR)是排查目录权限继承的常用姿势,每个层级都带完整属性。
3.14 --color:彩色输出的三种模式
--color 决定是否输出 ANSI 颜色码:never 关闭、always 强制开启、auto(默认)仅在输出连到终端时开启。管道场景下 auto 会自动"褪色",先实测这一点(cat -v 把控制字符显示为 ^[ 序列):
$ ls --color=always /root/demo/ls | cat -v | head -15
alpha-hard.txt
alpha.txt
big.bin
dir1
dir2
empty
link-alpha
med.bin
old.txt
older.txt
pipe.fifo
run
$ ls --color=never /root/demo/ls | head -5
alpha-hard.txt
alpha.txt
big.bin
dir1
dir2
TERM 未设置时 always 也给不出颜色。补上 TERM 再看 always 的真实输出——颜色码原形毕露:
$ export TERM=xterm-256color
$ ls --color=always /root/demo/ls | cat -v | head -15
alpha-hard.txt
alpha.txt
big.bin
^[[0m^[[01;34mdir1^[[0m
^[[01;34mdir2^[[0m
^[[01;34mempty^[[0m
^[[01;36mlink-alpha^[[0m
med.bin
old.txt
older.txt
^[[33mpipe.fifo^[[0m
^[[01;32mrun^[[0m
$ ls --color=never /root/demo/ls | head -4
alpha-hard.txt
alpha.txt
big.bin
dir1
解读颜色码:目录 01;34(加粗蓝)、软链 01;36(加粗青)、管道 33(黄)、可执行 01;32(加粗绿),普通文件无码。never 输出完全干净。配色由 LS_COLORS 环境变量控制(见 2.2 帮助末段),可用 dircolors 命令生成。
💡 提示:脚本/管道里出现
^[[01;34m乱码,几乎都是--color=always或 ls 别名强行带色导致的,处理办法是显式--color=never或ls \ls绕过别名。
3.15 错误场景与退出码
访问不存在的条目报错到 stderr,退出码为 2(对应 2.2 帮助 Exit status 的 "serious trouble"):
$ ls /root/demo/ls/nosuch.txt
ls: cannot access '/root/demo/ls/nosuch.txt': No such file or directory
$ ls /root/demo/ls/nosuch.txt; echo exit=$?
ls: cannot access '/root/demo/ls/nosuch.txt': No such file or directory
exit=2
💡 提示:脚本里判断"文件是否存在"不要依赖 ls 的退出码(1 与 2 混杂且语义是"能否访问"),用
test -e/[[ -e ]]更准确。
四、实战示例
4.1 统计目录条目数
-1 单列输出交给 wc 计数,是最稳的条目统计法(不受终端列宽影响,且 -1 不含隐藏项):
$ ls -1 /root/demo/ls | wc -l
12
结果 12 与 3.1 的可见条目数一致;要含隐藏文件改用 ls -1A | wc -l。
4.2 快速查看最近改动的文件
-lt 新文件在前,head 取前几名就是"最近动过什么":
$ ls -lt /root/demo/ls | head -4
total 56
-rwxr-xr-x 1 root root 26936 Oct 15 06:10 run
prw-r--r-- 1 root root 0 Oct 15 06:10 pipe.fifo
lrwxrwxrwx 1 root root 9 Oct 15 06:10 link-alpha -> alpha.txt
反向需求"最久未动的文件"(清理候选)用 -ltr | head。
4.3 管道过滤只留目录
-F 的目录标记 / 配合 grep 可只留目录行:
$ ls -F /root/demo/ls | grep /
dir1/
dir2/
empty/
与 3.10 的 ls -d */ 等效;输出要给下游脚本用时记得尾部的 / 是标记字符,按需处理。
4.4 查看子目录内容与占用
对任意子目录直接列长格式,total 行给出该子目录的磁盘占用:
$ ls -lh /root/demo/ls/dir1/sub
total 4.0K
-rw-r--r-- 1 root root 5 Oct 15 06:10 deep.txt
total 4.0K 是 sub 目录自身的 1K 块占用(-h 已换算),文件 deep.txt 实际 5 字节。
五、注意事项与常见问题
Q1:ls 默认按什么排序?会混排文件和目录吗?
按条目名称字母序,文件与目录混排(见 3.1 实测,dir1 排在 big.bin 之后)。要目录分组加 --group-directories-first;一旦使用 -t/-S 等排序参数,名称序即失效。
Q2:ls -l 里目录的大小为什么都是 4096?
那是目录条目表自身的大小(ext4 的一个块),不是目录内容的累计大小;内容的真实占用看首行 total 或用 du(见 3.2 第 5 段解读与 4.4 实测)。
Q3:首行 total 56 是什么单位?
目录下所有条目按 1024 字节块计的磁盘占用合计(-k 可显式指定 1K 块),不是文件字节数之和——稀疏文件、块对齐都会让它与字节数之和不一致。
Q4:-a 与 -A 到底差在哪?
只差 . 与 .. 两项:-a 显示,-A 不显示,隐藏条目(如 .hidden)两者都显示(见 3.3、3.4 对照)。
Q5:时间列有时是"时:分"有时是"年",以哪个为准?
六个月内的修改时间显示"月 日 时:分",超过六个月或未来时间显示"月 日 年"(实测 old.txt 为 Jan 1 2025、older.txt 为 Jun 1 2024)。需要精确时间用 --time-style=long-iso(3.2 实测)。
Q6:管道/文件里出现 ^[[01;34m 这类乱码怎么处理?
那是 ANSI 颜色码,说明 ls 被强制带色输出(--color=always 或别名)。显式加 --color=never,或用 command ls/\ls 绕过别名(见 3.14 实测与解读)。
Q7:ls 的退出码 0/1/2 各代表什么? 帮助原文 Exit status:0 正常;1 次要问题(如某个子目录无法访问);2 严重问题(命令行参数无法访问,实测 exit=2,见 3.15)。脚本里别用它判断文件存在性,用 test -e。
Q8:想按大小找大文件,-S 排出来的怎么还有 0 字节的文件?
-S 排的是当前一层,0 字节文件(与命名管道)会排在末尾而非消失;且目录恒按 4096 参与(见 3.8 实测解读)。要跨层级找大文件用 du 或 find -size。
六、参考链接
- GNU coreutils 官方手册(ls 章节):https://www.gnu.org/software/coreutils/manual/html_node/ls-invocation.html
- 在线文档:https://www.gnu.org/software/coreutils/ls
- LS_COLORS 配置生成:本机执行
dircolors -p(Ubuntu 22.04 内置 dircolors 命令) - 本机帮助:
ls --help、man ls、info '(coreutils) ls invocation'