Linux 基础命令复习手册
Linux 基础命令复习手册
目标:能独立完成文件操作、内容检索、管道组合和日志查看,并能解释命令背后的工作方式。示例统一使用普通用户提示符
$;#表示 root,复制命令时不要把提示符一起复制。
1. 高频命令总表
| 任务 | 首选命令 | 高频选项/写法 |
|---|---|---|
| 查看目录 | ls |
-l、-a、-h、-t |
| 切换/确认目录 | cd、pwd |
cd ..、cd -、cd ~ |
| 创建目录/文件 | mkdir、touch |
mkdir -p |
| 查看文件 | cat、less、head、tail |
less -N、tail -f、tail -F |
| 查看文件信息 | file、stat |
stat 文件 |
| 复制/移动 | cp、mv |
cp -a、cp -r、-i |
| 删除 | rm、rmdir |
rm -r、rm -i |
| 查找文件 | find |
-name、-type、-size、-mtime |
| 查找命令 | type、command -v |
type -a |
| 过滤内容 | grep |
-n、-i、-r、-E、-v |
| 统计内容 | wc |
-l、-w、-c、-m |
| 排序去重 | sort、uniq |
sort -n、sort -u、uniq -c |
| 提取列 | cut、awk |
cut -d: -f1 |
| 管道 | ` | ` |
| 重定向 | >、>>、2> |
覆盖、追加、重定向错误 |
| 同时看并保存 | tee |
`命令 |
| 编辑文件 | vim |
i、Esc、:wq、:q! |
| 查帮助 | --help、man |
man 5 passwd |
必须认识的目录
| 目录 | 主要内容 |
|---|---|
/ |
整棵目录树的根 |
/home |
普通用户家目录 |
/root |
root 的家目录,不是根目录 / |
/etc |
系统和服务配置 |
/var |
经常变化的数据,如日志、缓存、队列 |
/var/log |
常见日志目录 |
/usr/bin |
大量普通命令 |
/usr/sbin |
大量系统管理命令 |
/tmp |
临时文件,可能被系统清理 |
/opt |
可选的第三方软件 |
/srv |
服务对外提供的数据 |
/dev |
设备文件 |
/proc |
内核和进程信息的虚拟文件系统 |
/sys |
设备与内核对象信息的虚拟文件系统 |
2. 先准备一套统一练习数据
后面的命令都围绕 ~/linux-lab 演示:
[mia@linux ~]$ mkdir -p ~/linux-lab/{app,data,logs,backup}
[mia@linux ~]$ cat > ~/linux-lab/data/users.txt <<'EOF'
1001 alice backend active
1002 bob frontend active
1003 carol backend disabled
1004 dave ops active
EOF
[mia@linux ~]$ cat > ~/linux-lab/logs/app.log <<'EOF'
2026-07-29 09:00:01 INFO server started port=8000
2026-07-29 09:02:16 INFO GET /posts status=200
2026-07-29 09:03:40 ERROR database timeout request_id=r101
2026-07-29 09:04:03 WARN slow request cost=1.82s
2026-07-29 09:05:27 ERROR permission denied path=/srv/app/upload
EOF
[mia@linux ~]$ printf 'DEBUG=false\nPORT=8000\n' > ~/linux-lab/app/config.env
[mia@linux ~]$ touch ~/linux-lab/app/main.py
查看结构:
[mia@linux ~]$ find ~/linux-lab -maxdepth 2 -printf '%P\n' | sort
app
app/config.env
app/main.py
backup
data
data/users.txt
logs
logs/app.log
开头出现的空行代表 ~/linux-lab 本身;这是 find 的正常结果。
3. Linux 目录树与路径
3.1 Linux 只有一棵目录树
Windows 常见 C:\、D:\ 多个盘符;Linux 从唯一的根目录 / 开始。其他磁盘和文件系统通常被挂载到这棵树的某个目录。
/
├── etc
├── home
│ └── mia
├── usr
├── var
└── ...
3.2 绝对路径与相对路径
| 路径 | 起点 | 示例 |
|---|---|---|
| 绝对路径 | 根目录 / |
/home/mia/linux-lab/logs/app.log |
| 相对路径 | 当前工作目录 | logs/app.log |
[mia@linux ~]$ cd ~/linux-lab
[mia@linux linux-lab]$ pwd
/home/mia/linux-lab
[mia@linux linux-lab]$ cat logs/app.log
2026-07-29 09:00:01 INFO server started port=8000
...
[mia@linux linux-lab]$ cat /home/mia/linux-lab/logs/app.log
2026-07-29 09:00:01 INFO server started port=8000
...
3.3 特殊路径
| 写法 | 含义 |
|---|---|
. |
当前目录 |
.. |
上一级目录 |
~ |
当前用户家目录 |
~alice |
用户 alice 的家目录 |
- |
cd 中表示上一次所在目录 |
[mia@linux linux-lab]$ cd logs
[mia@linux logs]$ cd ..
[mia@linux linux-lab]$ cd -
/home/mia/linux-lab/logs
[mia@linux logs]$ cd
[mia@linux ~]$
cd 不带参数等价于回到当前用户的家目录。
3.4 文件名、隐藏文件与大小写
- 以
.开头的名称默认隐藏,例如.bashrc。 - Linux 文件名通常区分大小写:
App.py与app.py是两个名称。 - 扩展名不决定文件本质,
file会根据内容判断类型。
[mia@linux ~]$ ls
linux-lab
[mia@linux ~]$ ls -a
. .. .bashrc .ssh linux-lab
[mia@linux ~]$ file ~/linux-lab/logs/app.log
/home/mia/linux-lab/logs/app.log: ASCII text
4. 命令的基本结构
常见形式:
command [options] [arguments]
[mia@linux ~]$ ls -lah ~/linux-lab
ls:命令;-l、-a、-h:选项;~/linux-lab:参数。
短选项常可合并,下面三种通常等价:
$ ls -l -a -h
$ ls -lah
$ ls -hal
长选项通常以两个连字符开头:
$ ls --all --human-readable
4.1 如何查帮助
[mia@linux ~]$ ls --help | head
Usage: ls [OPTION]... [FILE]...
List information about the FILEs ...
[mia@linux ~]$ man ls
LS(1) User Commands LS(1)
在 man 中:
| 按键 | 作用 |
|---|---|
Space / PageDown |
下一页 |
b / PageUp |
上一页 |
/word |
向下搜索 |
n / N |
下一个/上一个匹配 |
q |
退出 |
手册分章节,例如:
$ man 1 passwd # passwd 命令
$ man 5 passwd # /etc/passwd 文件格式
5. 查看目录:ls
[mia@linux ~]$ ls -lah ~/linux-lab
total 0
drwxr-xr-x 6 mia mia 59 Jul 29 09:00 .
drwx------ 8 mia mia 190 Jul 29 08:50 ..
drwxr-xr-x 2 mia mia 39 Jul 29 09:00 app
drwxr-xr-x 2 mia mia 6 Jul 29 09:00 backup
drwxr-xr-x 2 mia mia 23 Jul 29 09:00 data
drwxr-xr-x 2 mia mia 21 Jul 29 09:00 logs
常用选项:
| 选项 | 含义 |
|---|---|
-l |
长格式 |
-a |
包括隐藏项 |
-h |
配合 -l,用 KiB、MiB、GiB 等易读单位 |
-t |
按修改时间排序 |
-r |
反向排序 |
-d |
查看目录本身,不列出目录内容 |
-i |
显示 inode 号 |
ls -l 一行大致包含:
-rw-r--r-- 1 mia developers 245 Jul 29 09:05 app.log
│ │ │ │ │ │ └─ 名称
│ │ │ │ │ └─ 修改时间
│ │ │ │ └─ 大小
│ │ │ └─ 所属组
│ │ └─ 所属用户
│ └─ 硬链接数
└─ 文件类型与权限
不要用解析 ls 输出的方式编写严肃脚本;文件名可能包含空格、换行等特殊字符。脚本中更适合使用 find -print0 等安全接口。
6. 创建目录和文件
6.1 mkdir
[mia@linux ~]$ mkdir ~/demo
[mia@linux ~]$ mkdir ~/a/b/c
mkdir: cannot create directory ‘/home/mia/a/b/c’: No such file or directory
[mia@linux ~]$ mkdir -p ~/a/b/c
[mia@linux ~]$ ls -d ~/a/b/c
/home/mia/a/b/c
-p:父目录不存在时一起创建;目录已存在时不报错。- 一次创建多个同级目录可用花括号展开:
$ mkdir -p project/{src,tests,docs,logs}
花括号展开由 Shell 完成,不是 mkdir 独有功能。
6.2 touch
[mia@linux ~]$ touch notes.txt
[mia@linux ~]$ ls -l notes.txt
-rw-r--r-- 1 mia mia 0 Jul 29 10:12 notes.txt
touch 的准确作用是更新访问/修改时间;文件不存在时才会顺便创建空文件。
[mia@linux ~]$ stat -c '%y %n' notes.txt
2026-07-29 10:12:00.000000000 -0700 notes.txt
[mia@linux ~]$ touch notes.txt
[mia@linux ~]$ stat -c '%y %n' notes.txt
2026-07-29 10:15:34.000000000 -0700 notes.txt
6.3 file 与 stat
[mia@linux ~]$ file ~/linux-lab/app/main.py
/home/mia/linux-lab/app/main.py: empty
[mia@linux ~]$ stat ~/linux-lab/logs/app.log
File: /home/mia/linux-lab/logs/app.log
Size: 281 Blocks: 8 IO Block: 4096 regular file
Access: (0644/-rw-r--r--) Uid: (1000/mia) Gid: (1000/mia)
7. 查看文件内容
7.1 怎么选命令
| 场景 | 命令 |
|---|---|
| 小文件一次全部输出 | cat file |
| 大文件分页查看 | less file |
| 查看开头 | head file |
| 查看结尾 | tail file |
| 持续跟踪日志 | tail -f file 或 tail -F file |
| 带行号查看 | nl -ba file 或 less -N file |
7.2 cat
[mia@linux ~]$ cat ~/linux-lab/app/config.env
DEBUG=false
PORT=8000
[mia@linux ~]$ cat -n ~/linux-lab/app/config.env
1 DEBUG=false
2 PORT=8000
cat 还能连接多个文件:
$ cat part1.txt part2.txt > all.txt
7.3 less
[mia@linux ~]$ less -N /etc/services
常用按键与 man 类似:Space 翻页、/关键词 搜索、n 下一个、q 退出。less 通常比 more 功能更完整。
7.4 head 与 tail
[mia@linux ~]$ head -n 2 ~/linux-lab/logs/app.log
2026-07-29 09:00:01 INFO server started port=8000
2026-07-29 09:02:16 INFO GET /posts status=200
[mia@linux ~]$ tail -n 2 ~/linux-lab/logs/app.log
2026-07-29 09:04:03 WARN slow request cost=1.82s
2026-07-29 09:05:27 ERROR permission denied path=/srv/app/upload
持续追踪:
[mia@linux ~]$ tail -f ~/linux-lab/logs/app.log
2026-07-29 09:05:27 ERROR permission denied path=/srv/app/upload
另一个终端追加内容:
[mia@linux ~]$ echo '2026-07-29 09:08:11 INFO worker ready' >> ~/linux-lab/logs/app.log
tail -F 在日志轮转、文件被重新创建后会尝试继续跟踪,比 -f 更适合长期盯日志。
8. 复制、移动与删除
8.1 cp
[mia@linux ~]$ cp ~/linux-lab/app/config.env ~/linux-lab/backup/config.env.bak
[mia@linux ~]$ cp -r ~/linux-lab/app ~/linux-lab/backup/
[mia@linux ~]$ cp -a ~/linux-lab/app ~/linux-lab/backup/app-full
| 选项 | 含义 |
|---|---|
-r / -R |
递归复制目录 |
-a |
归档复制,尽量保留权限、时间、链接等属性 |
-i |
覆盖前询问 |
-n |
不覆盖已有目标 |
-v |
显示操作过程 |
复制多个源时,最后一个参数必须是已存在的目录:
$ cp a.txt b.txt backup/
8.2 mv
mv 同时承担移动和重命名:
[mia@linux ~]$ mv old.txt new.txt
[mia@linux ~]$ mv new.txt ~/linux-lab/backup/
- 目标不存在:通常表示重命名。
- 目标是已存在的目录:移动到该目录内。
- 同一文件系统内移动通常只修改目录项,很快;跨文件系统时可能变成复制后删除。
8.3 rm
[mia@linux ~]$ rm old.log
[mia@linux ~]$ rm -r old-directory
[mia@linux ~]$ rm -i important.conf
rm: remove regular file 'important.conf'? n
| 选项 | 含义 |
|---|---|
-r |
递归删除目录 |
-f |
强制,不询问并忽略不存在的文件 |
-i |
每次删除前询问 |
-I |
大量删除或递归删除前询问一次 |
rm 默认是否询问与别名和选项有关,不是简单按“普通用户/root”区分。
8.4 删除前的安全习惯
# 1. 先打印目标
[mia@linux logs]$ printf '<%s>\n' *.log
<app.log>
<old.log>
# 2. 再删除,并让危险操作询问一次
[mia@linux logs]$ rm -I -- *.log
rm: remove 2 arguments? n
- 先用
pwd、ls或printf确认当前目录和通配结果。 --表示选项结束,可安全处理名称以-开头的文件。- 不要执行
rm -rf /、rm -rf /*或目标变量未经检查的递归删除。 - 命令行
rm通常不经过回收站。
删除空目录可用:
$ rmdir empty-directory
9. 通配符、引号与命令替换
9.1 通配符
| 写法 | 匹配 |
|---|---|
* |
任意长度字符,通常不跨 / |
? |
任意一个字符 |
[abc] |
a、b、c 中任一个 |
[0-9] |
任一个数字 |
[!0-9] |
任一个非数字字符 |
[mia@linux logs]$ printf '%s\n' *.log
app.log
old.log
[mia@linux data]$ printf '%s\n' user?.txt
user1.txt
user2.txt
通配符一般先由 Shell 展开,再把结果交给命令。
9.2 单引号、双引号与不加引号
[mia@linux ~]$ name='Linux'
[mia@linux ~]$ echo '$name'
$name
[mia@linux ~]$ echo "$name"
Linux
[mia@linux ~]$ echo *.txt
notes.txt report.txt
[mia@linux ~]$ echo "*.txt"
*.txt
| 写法 | 变量展开 | 命令替换 | 通配展开 | 保留空格 |
|---|---|---|---|---|
| 不加引号 | 是 | 是 | 是 | 否 |
"双引号" |
是 | 是 | 否 | 是 |
'单引号' |
否 | 否 | 否 | 是 |
变量引用通常写成 "$var",避免空格和通配符造成意外拆分。
9.3 命令替换
推荐使用 $(...),可读性和嵌套性优于旧式反引号:
[mia@linux ~]$ echo "当前目录:$(pwd)"
当前目录:/home/mia
[mia@linux ~]$ today=$(date +%F)
[mia@linux ~]$ echo "$today"
2026-07-29
10. 查找命令与文件
10.1 type、command -v、which
[mia@linux ~]$ type cd
cd is a shell builtin
[mia@linux ~]$ type -a python
python is /home/mia/venv/bin/python
python is /usr/bin/python
[mia@linux ~]$ command -v grep
/usr/bin/grep
type能识别别名、函数、Shell 内建和外部命令。command -v适合脚本判断命令是否存在。which主要搜索PATH中的可执行文件,对别名和内建命令不一定可靠。
10.2 find 基本结构
find 搜索起点 条件 动作
按名称:
[mia@linux ~]$ find ~/linux-lab -name 'app.log'
/home/mia/linux-lab/logs/app.log
[mia@linux ~]$ find ~/linux-lab -iname '*.ENV'
/home/mia/linux-lab/app/config.env
通配模式要加引号,避免被当前 Shell 提前展开。
按类型:
$ find ~/linux-lab -type f # 普通文件
$ find ~/linux-lab -type d # 目录
$ find ~/linux-lab -type l # 符号链接
按大小:
$ find /var/log -type f -size +100M
$ find . -type f -size -10k
按修改时间:
$ find . -type f -mtime -1 # 约 24 小时内修改
$ find . -type f -mtime +30 # 超过约 30 天
$ find . -type f -mmin -10 # 约 10 分钟内修改
组合条件:
$ find . -type f \( -name '*.log' -o -name '*.txt' \)
$ find . -type f -name '*.log' ! -name 'debug.log'
对结果执行命令:
[mia@linux ~]$ find ~/linux-lab/logs -type f -name '*.log' \
> -exec grep -Hn 'ERROR' {} +
/home/mia/linux-lab/logs/app.log:3:2026-07-29 09:03:40 ERROR database timeout request_id=r101
/home/mia/linux-lab/logs/app.log:5:2026-07-29 09:05:27 ERROR permission denied path=/srv/app/upload
{} + 会把多个结果成批传给命令,通常比每个文件执行一次的 {} \; 更高效。
11. 文本过滤与统计
11.1 grep
[mia@linux ~]$ grep -n 'ERROR' ~/linux-lab/logs/app.log
3:2026-07-29 09:03:40 ERROR database timeout request_id=r101
5:2026-07-29 09:05:27 ERROR permission denied path=/srv/app/upload
常用选项:
| 选项 | 含义 |
|---|---|
-n |
显示行号 |
-i |
忽略大小写 |
-v |
反选,不含匹配内容 |
-r |
递归搜索目录 |
-l |
只显示匹配到的文件名 |
-c |
显示每个文件的匹配行数 |
-E |
使用扩展正则表达式 |
-F |
把模式当普通字符串,不解释正则符号 |
-A 2 |
显示匹配行及后 2 行 |
-B 2 |
显示匹配行及前 2 行 |
-C 2 |
显示匹配行前后各 2 行 |
[mia@linux ~]$ grep -E 'ERROR|WARN' ~/linux-lab/logs/app.log
2026-07-29 09:03:40 ERROR database timeout request_id=r101
2026-07-29 09:04:03 WARN slow request cost=1.82s
2026-07-29 09:05:27 ERROR permission denied path=/srv/app/upload
[mia@linux ~]$ grep -rln 'DEBUG=false' ~/linux-lab
/home/mia/linux-lab/app/config.env
11.2 wc
[mia@linux ~]$ wc ~/linux-lab/data/users.txt
4 16 105 /home/mia/linux-lab/data/users.txt
默认依次显示行数、单词数、字节数。
$ wc -l file # 行数
$ wc -w file # 单词数
$ wc -c file # 字节数
$ wc -m file # 字符数
UTF-8 中文字符通常占多个字节,因此 -c 与 -m 可能不同。
11.3 sort、uniq、cut
统计每种状态的人数:
[mia@linux ~]$ awk '{print $4}' ~/linux-lab/data/users.txt | sort | uniq -c
3 active
1 disabled
uniq 只合并相邻重复行,所以一般先 sort。
从 /etc/passwd 提取用户名和登录 Shell:
[mia@linux ~]$ cut -d: -f1,7 /etc/passwd | head
root:/bin/bash
bin:/sbin/nologin
daemon:/sbin/nologin
...
12. 管道与重定向
12.1 三个标准流
| 编号 | 名称 | 默认位置 |
|---|---|---|
0 |
标准输入 stdin | 键盘 |
1 |
标准输出 stdout | 终端 |
2 |
标准错误 stderr | 终端 |
12.2 管道 |
管道把左侧命令的标准输出交给右侧命令的标准输入:
[mia@linux ~]$ grep 'ERROR' ~/linux-lab/logs/app.log | wc -l
2
[mia@linux ~]$ ps -ef | grep '[g]unicorn'
mia 3184 1 0 09:00 ? 00:00:01 gunicorn: master [config.wsgi]
grep '[g]unicorn' 可以避免把当前 grep gunicorn 自己匹配出来。更直接的做法是:
$ pgrep -af gunicorn
管道默认不传递标准错误:
$ find / -name '*.conf' 2>/dev/null | head
12.3 输出重定向
$ echo 'DEBUG=false' > config.env # 覆盖标准输出
$ echo 'PORT=8000' >> config.env # 追加标准输出
$ command 2> error.log # 只重定向错误
$ command > output.log 2> error.log # 输出和错误分开
$ command > all.log 2>&1 # 二者写入同一文件
$ command &> all.log # Bash 简写
$ command > /dev/null 2>&1 # 丢弃输出与错误
顺序很重要:
$ command > all.log 2>&1 # stderr 跟随已经指向 all.log 的 stdout
$ command 2>&1 > all.log # stderr 先指向终端,之后只有 stdout 改到文件
12.4 输入重定向与 Here Document
$ wc -l < users.txt
4
批量写入多行文本:
[mia@linux ~]$ cat > settings.ini <<'EOF'
[app]
debug = false
port = 8000
EOF
分隔符加单引号后,正文中的 $变量 和 $(命令) 不会展开。
12.5 tee
既在屏幕显示又保存:
[mia@linux ~]$ grep -E 'ERROR|WARN' ~/linux-lab/logs/app.log | tee ~/linux-lab/backup/problems.log
2026-07-29 09:03:40 ERROR database timeout request_id=r101
2026-07-29 09:04:03 WARN slow request cost=1.82s
2026-07-29 09:05:27 ERROR permission denied path=/srv/app/upload
追加使用 tee -a。写入需要 root 权限的文件时:
$ echo '127.0.0.1 forum.local' | sudo tee -a /etc/hosts
sudo echo ... > /etc/hosts 往往失败,因为重定向由当前普通 Shell 提前完成,sudo 只作用于 echo。
13. 命令连接与退出状态
| 写法 | 含义 |
|---|---|
cmd1 ; cmd2 |
无论前者成功与否都执行后者 |
cmd1 && cmd2 |
前者成功才执行后者 |
| `cmd1 | |
cmd1 | cmd2 |
前者输出作为后者输入 |
[mia@linux ~]$ mkdir release && cp app.py release/
[mia@linux ~]$ test -f config.env || echo 'config.env 不存在'
config.env 不存在
Linux 命令通常用退出状态表示结果:
0:成功;- 非
0:失败或出现特定情况。
[mia@linux ~]$ grep 'ERROR' ~/linux-lab/logs/app.log >/dev/null
[mia@linux ~]$ echo $?
0
[mia@linux ~]$ grep 'FATAL' ~/linux-lab/logs/app.log >/dev/null
[mia@linux ~]$ echo $?
1
$? 只保存最近一条前台命令的状态,应立即查看。
14. 安全地批量处理文件:xargs
简单形式:
$ printf '%s\n' a.log b.log | xargs rm
但文件名可能包含空格或换行,严肃场景使用 NUL 分隔:
$ find logs -type f -name '*.log' -print0 | xargs -0 grep -Hn 'ERROR'
许多场景可直接用 find -exec ... {} +,这样不需要额外考虑结果如何传递。
15. Vim 面试够用版
15.1 三种主要模式
| 模式 | 进入方式 | 作用 |
|---|---|---|
| 普通模式 | 打开文件或按 Esc |
移动、复制、删除、搜索 |
| 插入模式 | i、a、o 等 |
输入文字 |
| 命令行模式 | 普通模式按 :、/、? |
保存、退出、搜索、替换 |
[mia@linux ~]$ vim ~/linux-lab/app/config.env
最短操作流程:
i 进入插入模式
输入内容
Esc 回到普通模式
:wq 保存并退出
15.2 高频按键
| 按键 | 作用 |
|---|---|
h j k l |
左、下、上、右 |
0 / $ |
行首/行尾 |
gg / G |
文件首/文件尾 |
w / b |
下一个/上一个单词 |
i / a |
光标前/后插入 |
o / O |
下方/上方新建一行 |
dd |
删除/剪切当前行 |
yy |
复制当前行 |
p |
粘贴到光标后 |
u |
撤销 |
Ctrl+r |
重做 |
/word |
向下搜索 |
n / N |
下一个/上一个匹配 |
15.3 保存、退出与替换
| 命令 | 作用 |
|---|---|
:w |
保存 |
:q |
退出 |
:wq 或 ZZ |
保存并退出 |
:q! |
放弃修改并退出 |
:set number |
显示行号 |
:%s/old/new/g |
全文件替换 |
:%s/old/new/gc |
全文件替换,每次确认 |
16. 高频实战题
16.1 统计日志中 ERROR 数量
[mia@linux ~]$ grep -c 'ERROR' ~/linux-lab/logs/app.log
2
若需要统计匹配结果行数,也可:
$ grep 'ERROR' app.log | wc -l
16.2 找出 /var/log 下大于 100 MiB 的日志
$ sudo find /var/log -type f -name '*.log' -size +100M -print
16.3 查找项目中写死的密码字段
$ grep -RniE 'password|secret|token' ./project \
--exclude-dir=.git --exclude='*.pyc'
16.4 保留最近结果,同时记录错误
$ python manage.py migrate > migrate.log 2>&1
$ tail -n 30 migrate.log
16.5 把最近一天的 .log 文件归档到目录
先只查看:
$ find ./logs -type f -name '*.log' -mtime -1 -print
确认后再复制:
$ mkdir -p backup/recent
$ find ./logs -type f -name '*.log' -mtime -1 -exec cp -t backup/recent -- {} +
17. 高频面试问答
17.1 绝对路径和相对路径有什么区别?
绝对路径从根目录 / 开始,不依赖当前目录;相对路径从当前工作目录开始,结果会受 pwd 影响。
17.2 > 和 >> 有什么区别?
> 覆盖目标文件,>> 追加到文件尾部。两者默认只处理标准输出,错误输出需要使用 2> 等写法。
17.3 管道和重定向有什么区别?
管道把一个命令的标准输出交给另一个命令的标准输入;重定向改变标准输入、标准输出或标准错误所连接的位置,通常是文件。
17.4 find 和 grep 的区别?
find 主要按名称、类型、大小、时间等文件属性查找文件;grep 主要在文本内容中查找匹配行。两者经常组合使用。
17.5 which 为什么找不到 cd?
cd 通常是 Shell 内建命令,不是通过 PATH 搜索的普通外部程序。使用 type cd 能正确识别它。
17.6 tail -f 与 tail -F 的区别?
-f 持续读取当前文件描述符;-F 还会按文件名重试,日志轮转导致原文件被替换时更容易继续追踪。
17.7 为什么 rm -rf 危险?
-r 会递归遍历目录,-f 取消确认和多数报错。如果路径、变量或通配符写错,可能快速删除大量数据,而且通常无法从回收站恢复。
17.8 单引号和双引号有什么区别?
单引号基本保留全部字面内容,不展开变量和命令;双引号会展开 $变量 和 $(命令),但保留空格并阻止通配展开。
17.9 2>&1 是什么意思?
让文件描述符 2(标准错误)指向文件描述符 1(标准输出)当前指向的位置。它与前后重定向的顺序有关。
17.10 如何统计出现次数最多的 IP?
假设访问日志第一列是 IP:
$ awk '{print $1}' access.log | sort | uniq -c | sort -nr | head
18. 最终自测
不看答案完成以下任务:
- 在家目录创建
review/{src,logs,backup}。 - 创建三行日志,其中两行包含
ERROR。 - 显示日志最后两行并持续跟踪。
- 统计
ERROR行数。 - 把标准输出和错误同时保存到
run.log。 - 查找当前目录下 24 小时内修改的
.py文件。 - 递归搜索项目中出现
DEBUG=True的文件并显示行号。 - 用一条命令把查询结果同时显示并保存。
- 解释
rm -rf "$target"中为什么变量必须加双引号,以及为什么执行前仍要验证目标。 - 在 Vim 中完成搜索、替换、保存退出。
一组参考命令:
$ mkdir -p ~/review/{src,logs,backup}
$ printf 'INFO start\nERROR db\nERROR permission\n' > ~/review/logs/app.log
$ tail -n 2 -f ~/review/logs/app.log
$ grep -c 'ERROR' ~/review/logs/app.log
$ command > ~/review/run.log 2>&1
$ find . -type f -name '*.py' -mtime -1
$ grep -RniF 'DEBUG=True' .
$ grep -n 'ERROR' ~/review/logs/app.log | tee ~/review/backup/errors.txt