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')";反引号则要转义 \`` 和 $`,容易写错,这也是我不用反引号的原因。
  • 【岗位标注】通用

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 才能拿到管道中真正的失败。
  • 【岗位标注】通用 / 运维 / 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 ]] 分组。
  • 【岗位标注】通用 / 运维

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 ((...)) 代替。
  • 【岗位标注】通用 / 运维

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 写在函数里会把整个流程干掉,这是常见事故。
  • 【岗位标注】通用 / DevOps

Q6. Shell 数组怎么用?什么时候用关联数组?

  • 【考察点】会数组说明脚本水平到中级;不会的人只能用字符串拼接硬凑
  • 【参考回答】索引数组:定义 arr=(a b c) 或 arr[0]=a,访问 ${arr[0]},全部元素 ${arr[@]},个数 `$