shell脚本
1、Shell 脚本开头 #!/bin/bash 作用是什么?
- 指定脚本解释器,告知系统用 bash 解析执行;不加会用系统默认 shell,语法可能报错。
2、脚本执行方式有几种?区别?
./test.sh:需要执行权限,在子 shell 运行bash test.sh:不需要执行权限,指定 bash 运行source test.sh/. test.sh:当前 shell 执行,变量全局生效
3、变量定义规则?
- 赋值
=左右不能空格 - 弱类型,无需声明类型
- 双引号解析变量,单引号原样输出
4、常用特殊变量
$0脚本名$1 $2第 1/2 个入参$#参数个数$@所有参数$?上一条命令退出状态码(0 成功,非 0 失败)$$当前进程 PID
5、数值比较符号
-eq等于、-ne不等于-gt大于、-lt小于-ge大于等于、-le小于等于
6、文件判断(超级高频)
-f 文件是否存在且为普通文件
-d 是否为目录
-e 文件/目录是否存在
-r 可读
-w 可写
-x 可执行
-z 字符串为空
-n 字符串非空
7、判断文件是否存在
if [ -f /etc/profile ];then
echo "文件存在"
else echo "不存在"
fi
[ ] 左右必须有空格
8、字符串判断
if [ "$name" == "test" ]
if [ -z "$str" ] # 判断空字符串
9、for 循环遍历、批量处理
# 1~10循环
for i in {1..10};do
echo $i
done
# 遍历目录文件
for file in *.log;do
echo $file
done
10、while 循环、逐行读取文件(面试重点)
while read line
do
echo $line
done < test.txt
11、文本处理三剑客
(1)grep 过滤
grep "error" app.log # 匹配包含error行
grep -v "info" app.log # 反向过滤,排除info
grep -n "warn" app.log # 显示行号
(2)sed 流编辑 / 替换
sed 's/123/456/g' test.txt # 全局替换
sed -i 's/a/b/g' test.txt # -i 直接修改原文件
sed -n '10,20p' test.txt # 截取10-20行
(3)awk 格式化输出、列截取(问最多)
awk '{print $1}' # 打印第一列
awk '{print $1,$3}' # 打印1、3列
awk -F: '{print $1}' /etc/passwd # 指定分隔符:
组合命令面试高频:
# 查看TCP连接数
netstat -an | grep tcp | wc -l
# 统计日志error行数
grep "ERROR" app.log | wc -l
12、运算符
(1)整数运算
a=10
b=20
c=$((a + b))
13、函数定义、传参
func(){
echo "接收参数:$1 $2"
}
func 100 200
14、基础理论
$?含义?
上一条命令执行返回值,0 成功,非 0 异常
- 管道
|作用?
将前一个命令输出,作为后一个命令输入
- 重定向 > 、>> 、2>&1 区别
>覆盖写入>>追加写入2>&1错误日志合并到标准输出
- 什么是僵尸进程、如何通过 shell 查找?
- 子进程已经退出,但父进程没有调用 wait () 获取它的退出状态,导致子进程的进程描述符没有被系统回收,处于僵死状态,这种进程叫僵尸进程,状态标识是 Z。
- 用
ps aux | grep -w Z或者ps -ef | grep defunct,STAT 列显示 Z 的就是僵尸进程。 - 僵尸进程已经死了,kill 没用。只能杀死父进程,重启系统
- crontab 定时任务语法(必考)
分 时 日 月 周 命令 * * * * * sh /opt/test.sh
15、判断服务是否存活,挂了自动重启
#!/bin/bash
# 服务名,可改成 nginx、mysql、docker 等
SERVICE="nginx"
# 检查进程是否存在
if pgrep -x "$SERVICE" >/dev/null
then
echo "$SERVICE 正在运行"
else
echo "$SERVICE 已停止,正在重启..."
systemctl start $SERVICE
# 再次检查是否启动成功
if pgrep -x "$SERVICE" >/dev/null
then
echo "重启成功!"
else
echo "重启失败!"
fi
fi
16、打包备份目录,带日期时间戳
#!/bin/bash
# 源目录(需要备份的文件夹)
SRC_DIR="/home/test"
# 备份存放目录
BAK_DIR="/tmp/backup"
# 备份文件名(带日期)
BAK_FILE="$BAK_DIR/backup_$(date +%Y%m%d_%H%M%S).tar.gz"
# 创建备份目录
mkdir -p $BAK_DIR
# 打包压缩
tar -zcvf $BAK_FILE $SRC_DIR
echo "备份完成:$BAK_FILE"
17、清理 7 天前的日志文件
#!/bin/bash
# 日志目录
LOG_DIR="/var/log"
# 清理7天前的 .log 文件
find $LOG_DIR -name "*.log" -mtime +7 -delete
echo "7天前日志清理完成!"
18、筛选日志中的 ERROR 并输出行数
#!/bin/bash
LOG_FILE="app.log"
# 统计 ERROR 行数
count=$(grep -c "ERROR" $LOG_FILE)
echo "ERROR 日志总数:$count 行"
# 输出所有 ERROR 行
grep "ERROR" $LOG_FILE
19、批量修改文件夹下所有文件后缀
#!/bin/bash
# 目标目录
DIR="./test"
# 旧后缀、新后缀
OLD_SUF="txt"
NEW_SUF="bak"
# 批量重命名
for file in $DIR/*.$OLD_SUF
do
mv $file ${file%.$OLD_SUF}.$NEW_SUF
done
echo "后缀修改完成!"
20、读取配置文件逐行处理
#!/bin/bash
CONFIG="config.txt"
# 逐行读取
while read line
do
# 跳过空行、注释行
if [ -z "$line" ] || [[ $line == \#* ]]; then
continue
fi
echo "读取配置:$line"
# 切割 key 和 value
key=$(echo $line | cut -d'=' -f1)
val=$(echo $line | cut -d'=' -f2)
echo "键:$key,值:$val"
done < $CONFIG
总结
- 服务监控:
pgrep查进程,不存在则systemctl start - 备份脚本:
tar + date +%Y%m%d - 清理日志:
find -mtime +7 -delete - 统计 ERROR:
grep -c ERROR - 批量改后缀:
for + mv + 字符串截取 - 逐行读配置:
while read line
浙公网安备 33010602011771号