跳转至

Linux 与 Shell 面试准备

📌 本文整理了 Linux 与 Shell 编程高频面试题 40 道,涵盖基础命令、文件系统、进程管理、网络、Shell 编程和系统管理等主题。


📚 一、Linux 基础与文件系统(10题)

1. Linux 中硬链接和软链接的区别?

Bash
# 软链接(符号链接)
ln -s target link_name
# - 类似 Windows 快捷方式
# - 有独立的 inode
# - 可以跨文件系统
# - 可以链接目录
# - 原文件删除后链接失效(悬空链接)

# 硬链接
ln target link_name
# - 共享同一个 inode
# - 不能跨文件系统
# - 不能链接目录(避免循环)
# - 原文件删除后硬链接仍有效(引用计数>0)
# - 任何一个硬链接修改,所有都变化

2. Linux 文件权限中 rwx 对目录意味着什么?

  • r(读):可以列出目录内容(ls)
  • w(写):可以在目录中创建、删除、重命名文件
  • x(执行):可以进入该目录(cd),可以访问目录中的文件
  • 没有 x 权限,即使有 r 也无法 ls 目录内容的详细信息;没有 x 就无法 cd 进入

3. chmod 755 是什么含义?

  • 7 (rwx) = 所有者有读、写、执行权限
  • 5 (r-x) = 组用户有读和执行权限
  • 5 (r-x) = 其他用户有读和执行权限
  • 常用于可执行文件和脚本
  • 二进制表示:111 101 101

4. 什么是 SUID、SGID 和 Sticky Bit?

Bash
# SUID (Set User ID) — 4000
chmod u+s file
# 执行时以文件所有者身份运行
# 典型:/usr/bin/passwd(普通用户可修改 /etc/shadow)

# SGID (Set Group ID) — 2000
chmod g+s dir
# 文件:执行时以组身份运行
# 目录:在该目录中创建的新文件继承目录的组

# Sticky Bit — 1000
chmod +t dir
# 只有文件所有者和 root 能删除该目录中的文件
# 典型:/tmp 目录

5. /proc 文件系统的作用?

/proc 是虚拟文件系统,提供内核和进程状态信息的接口。不占磁盘空间,只存在于内存。 - /proc/cpuinfo — CPU 信息 - /proc/meminfo — 内存信息 - /proc/PID/ — 进程信息 - /proc/sys/ — 内核参数(可通过 sysctl 修改)

6. Linux 启动过程?

  1. BIOS/UEFI — 硬件自检(POST),加载 Bootloader
  2. Bootloader(GRUB) — 加载内核
  3. 内核初始化 — 加载驱动,挂载根文件系统
  4. init/systemd(PID=1) — 用户空间初始进程
  5. 启动服务 — 按依赖关系启动系统服务
  6. 登录 — getty → login 或图形界面

7. 如何查看文件被哪个进程占用?

Bash
lsof /var/log/syslog         # 查看文件被谁打开
fuser -v /var/log/syslog     # 查看文件关联的进程
lsof +D /var/log/            # 目录中所有被打开的文件

8. inode 是什么?inode 耗尽怎么办?

inode 存储文件的元数据(权限、所有者、时间戳、数据块指针等)。每个文件占一个 inode。

inode 耗尽时无法创建新文件(即使磁盘有空间)。 解决:df -i 查看 inode 使用率,找出目录中的大量小文件并清理: find /path -xdev -type f | cut -d/ -f2-3 | sort | uniq -c | sort -rn | head

9. Linux 中有哪些文件类型?

Bash
# ls -l 第一个字符标识
# -  普通文件
# d  目录
# l  符号链接
# c  字符设备(如 /dev/tty)
# b  块设备(如 /dev/sda)
# s  套接字文件(如 /var/run/docker.sock)
# p  管道文件(命名管道,FIFO)

10. 如何找到系统中大于 100MB 的文件?

Bash
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null
find / -type f -size +100M -printf '%s %p\n' | sort -rn | head -20
du -ah / 2>/dev/null | sort -rh | head -20

📚 二、文本处理(8题)

11. grep、sed、awk 各自的适用场景?

  • grep:文本搜索和过滤(按行匹配模式)
  • sed:流式文本编辑(替换、删除、插入)
  • awk:结构化文本处理(按列操作、计算统计)

简单规则:找内容用 grep,改内容用 sed,算数据用 awk。

12. 如何统计文件中某个单词出现的次数?

Bash
grep -c "word" file           # 包含该词的行数
grep -o "word" file | wc -l   # 精确出现次数
awk '{for(i=1;i<=NF;i++) if($i=="word") count++} END{print count}' file

13. 如何去除文件中的重复行?

Bash
sort file | uniq              # 去除相邻重复行
sort -u file                  # 排序并去重
awk '!seen[$0]++' file        # 不排序去重(保持原始顺序)

14. 如何提取日志中特定时间段的内容?

Bash
awk '/2024-01-15 10:00/,/2024-01-15 11:00/' access.log
sed -n '/2024-01-15 10:00/,/2024-01-15 11:00/p' access.log

15. 如何合并两个文件的对应行?

Bash
paste file1 file2             # 按列合并(Tab分隔)
paste -d',' file1 file2       # 用逗号分隔
join file1 file2              # 按第一列合并(文件需先排序)

16. 如何实时查看日志文件的新增内容?

Bash
tail -f /var/log/syslog                     # 实时跟踪
tail -f /var/log/syslog | grep --line-buffered "error"  # 过滤
multitail /var/log/syslog /var/log/auth.log  # 同时监控多个
journalctl -f -u nginx                      # systemd 日志

17. 如何将文件中的 Tab 替换为空格?

Bash
expand file                   # Tab → 空格
sed 's/\t/    /g' file       # 替换为4个空格
tr '\t' ' ' < file           # Tab → 单个空格

18. 正则表达式中贪婪匹配和非贪婪匹配?

  • 贪婪匹配 .*:尽可能多地匹配(默认行为)
  • 非贪婪匹配 .*?:尽可能少地匹配(Perl 正则支持,基本正则不支持)

在 sed 中实现非贪婪:用 [^x]* 代替 .*(匹配到第一个 x 之前的字符)


📚 三、进程管理(7题)

19. 什么是僵尸进程?如何处理?

子进程终止后,父进程没有调用 wait() 回收,进程表中仍有条目。 查找:ps aux | awk '$8=="Z"' 解决:kill -SIGCHLD <父进程PID> 或杀死父进程让 init 回收。

20. SIGTERM 和 SIGKILL 的区别?

  • SIGTERM (15):请求终止,进程可以捕获并做清理工作再退出
  • SIGKILL (9):强制终止,不可捕获、不可忽略,直接由内核杀死
  • 正确做法:先 TERM,等几秒如果还在,再 KILL

21. 如何找出 CPU/内存使用最高的进程?

Bash
ps aux --sort=-%cpu | head -11          # CPU Top 10
ps aux --sort=-%mem | head -11          # 内存 Top 10
top -bn1 | head -17                     # 快照

22. 系统负载(load average)是什么?

等待 CPU 的进程数的时间平均值(⅕/15分钟)。在 N 核系统上: - load < N:CPU 未饱和 - load = N:CPU 刚好满载 - load > N:有进程在等待 CPU 查看:uptimecat /proc/loadavg

23. 如何让进程在后台运行并且退出终端后不停止?

Bash
nohup command > output.log 2>&1 &       # nohup + &
command & disown                         # disown
tmux / screen                            # 终端复用器(最佳实践)

24. 什么是 D 状态进程?

D 状态(Uninterruptible Sleep)是不可中断睡眠,通常发生在进程等待 I/O 操作(如磁盘读写)。不能被信号中断(包括 SIGKILL)。大量 D 状态进程说明 I/O 有问题。

25. fork 和 exec 的区别?

  • fork():创建子进程,子进程是父进程的副本(复制内存空间)
  • exec():用新程序替换当前进程的映像(PID 不变)
  • Shell 执行命令的过程:fork → 子进程 exec → 父进程 wait

📚 四、网络(7题)

26. 如何查看端口被哪个进程占用?

Bash
ss -tlnp | grep ":80"                  # ss(推荐)
netstat -tlnp | grep ":80"             # netstat
lsof -i :80                            # lsof
fuser 80/tcp                           # fuser

27. 如何排查网络不通?

  1. ping IP — 网络层连通性
  2. traceroute IP — 定位断点
  3. dig domain — DNS 解析
  4. telnet IP PORT — 端口连通性
  5. ss -tlnp — 本地服务监听检查
  6. iptables -L — 防火墙规则
  7. curl -v URL — 应用层检查

28. TCP 三次握手和四次挥手?

三次握手(建立连接): 1. 客户端 → SYN → 服务端 2. 服务端 → SYN+ACK → 客户端 3. 客户端 → ACK → 服务端

四次挥手(关闭连接): 1. 主动方 → FIN → 被动方 2. 被动方 → ACK → 主动方 3. 被动方 → FIN → 主动方 4. 主动方 → ACK → 被动方

29. TIME_WAIT 状态是什么?大量 TIME_WAIT 怎么办?

主动关闭连接方在发送最后一个 ACK 后进入 TIME_WAIT,等待 2MSL(通常 60 秒)。防止最后的 ACK 丢失导致对端重传 FIN。

大量 TIME_WAIT 的优化:

Bash
# /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1              # 允许重用
net.ipv4.tcp_fin_timeout = 30          # 缩短超时

30. scp 和 rsync 的区别?

  • scp:每次全量传输,简单但效率低
  • rsync:增量传输(只传差异),支持压缩、断点续传、排除规则
  • 频繁同步用 rsync,偶尔传文件用 scp

31. 如何配置 SSH 免密登录?

Bash
# 1. 生成密钥
ssh-keygen -t ed25519

# 2. 复制公钥
ssh-copy-id user@server

# 3. 确认权限
# ~/.ssh/ → 700
# ~/.ssh/authorized_keys → 600

32. iptables 的四表五链?

四表(优先级从高到低):raw → mangle → nat → filter 五链:PREROUTING → INPUT → FORWARD → OUTPUT → POSTROUTING 最常用:filter 表的 INPUT/OUTPUT/FORWARD 链


📚 五、Shell 编程(8题)

33. $@$* 的区别?

不加引号时相同。加引号: - "$@" → "arg1" "arg2" "arg3"(每个参数独立) - "$*" → "arg1 arg2 arg3"(所有参数合并为一个字符串) 遍历参数用 "$@"

34. [ ][[ ]] 的区别?

  • [ ] 是 POSIX 标准,兼容性好,相当于 test 命令
  • [[ ]] 是 Bash 扩展,支持正则 =~、模式匹配 ==、逻辑运算 &&/||
  • [[ ]] 内变量不需要引号(不会进行分词)

35. 如何获取脚本自身的完整路径?

Bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT_PATH="$(readlink -f "$0")"

36. 单引号和双引号的区别?

  • 双引号 "":允许变量替换 $var 和命令替换 $(cmd)
  • 单引号 '':原样输出所有内容,不做任何替换

37. set -e、set -u、set -o pipefail 的作用?

  • set -e:命令非零退出时立即退出脚本
  • set -u:引用未定义变量时报错退出
  • set -o pipefail:管道中任何命令失败,整个管道返回非零 生产脚本推荐:set -euo pipefail

38. 如何在 Shell 中实现并行执行?

Bash
# 方法1:后台执行 + wait
for server in web01 web02 web03; do
    ssh "$server" "uptime" &
done
wait     # 等待所有后台任务完成

# 方法2:xargs 并行
echo -e "web01\nweb02\nweb03" | xargs -P 3 -I {} ssh {} "uptime"

# 方法3:GNU parallel
parallel ssh {} "uptime" ::: web01 web02 web03

39. 如何在脚本中处理信号和清理?

Bash
#!/bin/bash
cleanup() {
    echo "执行清理..."
    rm -f /tmp/myapp.lock
}
trap cleanup EXIT           # 退出时清理
trap 'echo "中断"; exit 1' INT TERM  # 捕获 Ctrl+C

40. Crontab */5 * * * * 表示什么?如何调试 Crontab?

每5分钟执行一次。

调试: 1. 确保脚本有执行权限且用绝对路径 2. 脚本中设置 PATH 环境变量 3. 重定向输出:*/5 * * * * /opt/script.sh >> /var/log/cron_debug.log 2>&1 4. 查看 cron 日志:grep CRON /var/log/syslog


🎯 面试技巧

  1. 命令不能死记:说出命令时要解释参数含义
  2. 排查问题要有思路:从网络层到应用层,自上而下或自下而上
  3. Shell 题要关注边界:空值检查、权限问题、路径问题
  4. 实战经验加分:提到自己用脚本解决过的实际问题
  5. 安全意识:用 SIGTERM 不要上来就 SIGKILL,权限最小化原则

返回目录README