Shell 与 Python 面试问答(34 题)
本文整理了Shell 与 Python 面试问答(34 题)相关的 34 个高频面试问题,从基础到进阶再到生产实战层层递进,覆盖python、Linux、面试等核心考点,每题附参考回答与追问,适合面试前系统复习。
适用岗位:运维工程师 / 技术支持工程师 / AI 运维工程师 / DevOps 工程师
一、岗位高频速查
| 岗位 | 必考问题(高频 3-5 问) | 一句话要点 |
|---|---|---|
| 运维工程师 | 1. set -euo pipefail 每项什么含义?2. 排查磁盘满 / 负载高的命令链?3. 写一个每天 2 点执行的日志清理脚本(含 cron)?4. nohup / & / jobs 区别?后台任务怎么管?5. 脚本如何保证只跑一个实例? |
重点在”能用脚本把巡检 / 清理 / 备份自动化并扛得住故障”,每题都要能报出具体命令和退出码语义 |
| 技术支持工程师 | 1. 批量改 100 台机器配置你用什么方法?2. 脚本报错怎么定位(bash -x / 日志)?3. 同一个脚本重复执行会不会出问题(幂等)?4. Windows 与 Linux 脚本有什么差异?5. 你的拷贝工具比资源管理器快是怎么做到的? | 侧重”解决问题 + 可复现”,讲清楚工具的输入、输出、异常处理、失败重跑,别背概念 |
| AI 运维工程师 | 1. 用 requests 调大模型 API 如何做超时与重试?2. 多线程 / 多进程处理日志、批量请求怎么选?3. 异常处理与日志规范?4. Python 调用外部命令 subprocess?5. 大文件 / 大日志逐行处理不爆内存? | 几乎全 Python:超时、重试、限流、并发、日志、异常兜底是必背组合拳 |
| DevOps 工程师 | 1. CI 流水线脚本如何保证失败即停(exit code / pipefail)?2. 容器里调试脚本与宿主机有什么差异?3. Shell 与 Python 什么时候用哪个?4. 脚本如何做到幂等与可重入?5. 文本三剑客批量改配置? | 与运维高度重叠,另加”交付物是流水线 / 镜像里的脚本”,强调可维护性、参数化、退出码约定 |
补充:SRE、数据库运维等衍生岗位与”运维工程师”栏高度重叠;差异题(如 k8s 里调试、编排器集成)低频,了解即可,不必专门准备。
二、基础篇(12 题)
Q1. Shell 中单引号、双引号、反引号和 $() 有什么区别?
- 【考察点】变量替换、命令替换、分词(word splitting)三个基础概念是否真懂,还是只会背结论
- 【参考回答】先给结论:单引号里面是什么就是什么,不做任何替换;双引号里做变量替换和命令替换,但不做分词和通配符展开;反引号和
$()都是命令替换——执行里面的命令并把输出当字符串,$()可以嵌套、反斜杠处理更友好,所以统一推荐$()。举例:name=world; echo 'hello $name'输出字面量hello $name,echo "hello $name"输出hello world,echo "today: $(date +%F)"输出日期。我踩过的坑:echo $file不带引号会被分词,文件名带空格直接裂开,所以变量引用一律加双引号。 - 【追问】
- 追问 1:
echo $(ls)和echo "$(ls)"输出有什么区别?—— 不带引号时命令替换结果会被再次分词:多行被拍平成一行、连续空格被折叠;带引号保留换行和空格。处理文件列表时必须用"$(...)"或改用数组。 - 追问 2:
$()里引号怎么嵌套?—— 可以随意嵌套单双引号,如echo "$(echo 'a"b')";反引号则要转义\`` 和$`,容易写错,这也是我不用反引号的原因。
- 追问 1:
- 【岗位标注】通用
Q2. $?、$#、$@、$*、$$、$!、$0 分别是什么?
- 【考察点】特殊变量是排查脚本问题的基础,答不全基本说明没怎么写过错综的脚本
- 【参考回答】$? 是上一条命令的退出码,0 成功非 0 失败,这是脚本判断成败的基石;$# 是位置参数个数;$@ 是所有参数、每个参数独立成词(转发参数时用
"$@"),$* 是把所有参数拼成一个字符串(一般"$*"用于拼接);$$ 是当前 Shell 的 PID,常用于生成临时文件名tmp_$$;$! 是最近一个后台任务的 PID,配wait $!用;$0 是脚本名,$1~$9 是位置参数,超过 9 个用${10}。生产里最常用的是用 $? 判断命令成败,决定日志级别和退出码。 - 【追问】
- 追问 1:
"$@"和"$*"能举个实际例子吗?——f(){ for x in "$@"; do echo "[$x]"; done; },传f a "b c":"$@"输出[a]、[b c]两项;"$*"只输出[a b c]一项。把参数原样转交给子命令时必须用"$@"。 - 追问 2:怎么判断一个命令”失败”而不只是退出码非 0?—— 先看退出码语义:很多命令返回 1 是正常业务结果(如 grep 没匹配到、diff 有差异);再看 stderr 有没有输出;最后配合
set -o pipefail才能拿到管道中真正的失败。
- 追问 1:
- 【岗位标注】通用 / 运维 / DevOps
Q3. 条件判断里 [ ] 和 [[ ]] 和 test 有什么区别?文件判断和比较有哪些?
- 【考察点】脚本里的 if 用得对不对,能否避开常见语法坑
- 【参考回答】
test和[ ]是同一个命令,POSIX 兼容,要求变量加引号、运算符两边留空格;[[ ]]是 bash 内置关键字,不做分词和通配符展开,所以[[ -f $file ]]即使 $file 为空也不会报错,还支持=~正则和<>字典序比较——能写 bash 的脚本我尽量用[[ ]]。文件判断常用-f普通文件、-d目录、-e存在、-s非空、-r/-w/-x权限;整数比较用-eq -ne -gt -ge -lt -le,字符串用= != -z -n。经典坑:[ $n -gt 5 ]在 n 为空时报unary operator expected,[[ $n -gt 5 ]]则安全。 - 【追问】
- 追问 1:
[[ $a =~ ^[0-9]+$ ]]和[ $a =~ ... ]有差别吗?——=~是[[ ]]独有,写在[ ]里直接语法错误;正则表达式不用加引号。 - 追问 2:逻辑与或怎么写?——
[ ]里用-a / -o或&& / ||连接两个 test;[[ ]]直接&& || !,还能[[ (a -eq 1 && b -eq 2) || c ]]分组。
- 追问 1:
- 【岗位标注】通用 / 运维
Q4. for / while / until 三种循环分别什么场景?遍历文件内容怎么最稳?
- 【考察点】循环是脚本高频动作,重点看会不会踩”文件名带空格””空行”的坑
- 【参考回答】结论:for 适合遍历已知列表、数组、通配符展开结果——
for f in *.log或for i in {1..10};while 适合按条件循环和逐行读文件——while IFS= read -r line; do ...; done < file是逐行读的标准姿势,IFS=保留首尾空格、-r保留反斜杠,文件名带空格、换行都能处理;until 是 while 的取反,条件为假才循环,适合”等一个服务起来”:until curl -sf http://localhost:8080/health; do sleep 1; done。三个坑:for f in $(cat list)会被分词,文件名带空格直接裂开;for i in $(seq 1 10)不如for ((i=1; i<=10; i++));break/continue记得用。 - 【追问】
- 追问 1:如何安全地遍历 find 的结果?——
find . -name '*.log' -print0 | while IFS= read -r -d '' f; do ...; done,用 NUL 分隔,任何文件名都安全。注意管道版 while 跑在子 shell 里,循环里改的变量外面拿不到;要拿到就改用进程替换:while ...; done < <(find ...)。 - 追问 2:
for i in {1..100000}有什么问题?—— 大括号展开会先把 10 万个词生成到内存里,用seq或 C 风格for ((...))代替。
- 追问 1:如何安全地遍历 find 的结果?——
- 【岗位标注】通用 / 运维
Q5. Shell 函数怎么定义?变量作用域怎么回事?
- 【考察点】函数是脚本工程化的分水岭,答不出 local 基本等于没写过超过 100 行的脚本
- 【参考回答】定义是
func() { ...; }或function func { ...; },调用就是写函数名。函数里的变量默认是全局的——在函数里x=1会污染外部,这是新手最常踩的坑,所以函数内部变量一律local x=1。函数”返回值”有两套:return N设置退出码(0-255);echo 输出传给调用者,拿的时候用result=$(func)。注意区分”函数想打印给调用者的结果”和”函数里想留给自己看的日志”——日志要写 stderr:echo "debug" >&2,否则会被$(...)吞进返回值里。 - 【追问】
- 追问 1:
$(func)里函数中的local变量还能用吗?—— 能用,local 只是把作用域限制在函数内、函数结束即销毁;命令替换只是抓走 stdout,不影响作用域。 - 追问 2:函数里的
exit和return区别?——return只退出函数,exit退出整个脚本。误把exit写在函数里会把整个流程干掉,这是常见事故。
- 追问 1:
- 【岗位标注】通用 / DevOps
Q6. Shell 数组怎么用?什么时候用关联数组?
- 【考察点】会数组说明脚本水平到中级;不会的人只能用字符串拼接硬凑
- 【参考回答】索引数组:定义
arr=(a b c)或arr[0]=a,访问${arr[0]},全部元素${arr[@]},个数 `$