从 basename 到脚本安全输出,这篇只讲「拿到文件名」本身,不展开权限或时间戳。
一、TL;DR:按场景选命令
- 从完整路径里只取文件名:
basename /usr/bin/sort→sort。 - 当前目录单列纯文件名:
ls -1,适合传给其他命令。 - 只找某类文件:
find . -maxdepth 1 -name "*.log"。 - 文件名含空格/换行时脚本安全写法:
find . -maxdepth 1 -type f -print0 | xargs -0 -I{} basename "{}"。
二、basename:从路径中剥离目录
basename /usr/bin/sort
basename -s .h include/stdio.h
basename -a /var/log/syslog /etc/passwd
basename 只输出路径的最后一部分 [2]。加 -s 可以同时去掉后缀,加 -a 支持多个参数,输出按行分隔。它不检查文件是否存在,所以可以安全用于字符串处理。
实测输出:
sort
stdio
syslog
passwd
三、ls 的单列与过滤输出
ls -1
ls -1 *.conf
ls -F
ls 默认是横向多列,加 -1(数字一)强制单列 [1]。配合通配符时,shell 先做文件名扩展,再传给 ls,所以 ls -1 *.conf 只显示匹配的文件。-F 会在可执行文件后加 *、目录加 /、符号链接加 @,纯看文件名时建议关掉颜色(--color=never)。
实测输出:
archive.tar.gz
regular.txt
script.sh
四、find:按条件筛选文件名
find . -maxdepth 1 -type f -name "*.log"
find . -maxdepth 1 -name ".*"
find 默认递归,必须加 -maxdepth 1 限制当前目录 [3]。-name 用 shell 通配符匹配,-type f 只找普通文件,-name ".*" 能找到隐藏文件。find 会输出 ./ 前缀,如果只要纯文件名,可以加 -printf '%f\n'。
实测输出:
./regular.txt
五、脚本安全:处理空格与特殊字符
touch "file with spaces.txt" "weird\$name.log"
ls -1
ls -b
find . -maxdepth 1 -type f -print0 | xargs -0 -I{} basename "{}"
文件名含空格、换行或制表符时,for f in $(find . -name "*.txt") 会按空白拆分,结果错误。正确做法是让 find 用 NUL 分隔(-print0),再用 xargs -0 消费 [3]。ls -b 会把不可见字符转成 C 风格转义,方便调试 [1]。
实测输出:
file with spaces.txt
weird.log
六、回滚、排错与局限性
排错速查
| 现象 | 原因 | 处理 | |||
|---|---|---|---|---|---|
find 输出带 ./ |
默认行为 | 加 -printf '%f\n' 或接 `sed ‘s |
^\./ | ‘` | |
basename 返回空 |
输入是目录且以 / 结尾 |
先 realpath 或手动去尾 |
|||
ls -1 仍多列 |
输出被管道或重定向 | 正常,管道会自动单列;检查别名 alias ls |
|||
| 脚本丢失带空格的文件 | 用了 for f in $(find ...) |
改用 `-print0 | xargs -0` |
局限性
ls是用户态程序,不会枚举隐藏文件除非显式加-a;系统管理脚本不要依赖ls解析,直接用find或 shell 通配符。find . -maxdepth 1在含 NFS 挂载点的大目录里性能差,限定路径比限定深度更稳。basename和dirname只做字符串切割,不验证路径存在性。- 文件名含换行符时,即使
-print0也只能保证find不截断,下游工具仍需支持 NUL。
实测记录
- 环境:WSL2 Ubuntu 24.04,内核 5.15,GNU coreutils 9.4,GNU findutils 4.9.0。
basename /usr/bin/sort→sort;basename -s .h include/stdio.h→stdio。ls -1在管道中自动单列;ls -F给可执行文件追加*。find . -maxdepth 1 -type f -print0 | xargs -0 -I{} basename "{}"正确输出含空格的文件名。- 含
$的文件名在touch时需注意 shell 扩展;ls -b可显示转义形式。
参考资料
- [1] ls(1) – Linux manual page(ls(1))
- [2] basename(1) – Linux manual page(basename(1))
- [3] find(1) – Linux manual page(find(1))
文中主要命令已在 WSL Ubuntu(24.04)实测并核对其在 Debian 系与通用发行版的文档口径。