shell场景题
- 游戏开发
- 2025-09-16 19:36:02

目录
1、字符串及数组的操作
字符串截取与拼接
数组操作
2、流程控制
循环处理多个文件
条件判断
3、监控问题
检查服务器的磁盘使用率,并发送告警邮件
cpu使用率
检测进程状态,失败时重启
检测特定文本的变化
关键字检测监控
定时清理临时文件
4、top、free、df
top命令
free命令
df命令
5、脚本处理输入参数
访问命令行参数
处理选项和参数
6、管道pipline机制及其应用
7、awk、grep、sed、find、head、tail、tr、cut的使用
grep:文本搜索工具
常用选项
sed流编辑器
常用选项
find文件查找工具
常用选项
tail 命令
常用选项:
head命令
常用选项:
tr 命令
常用选项:
cut命令
常用选项:
综合例子
查找日志文件中的错误并统计
输出文本第十行
统计词频
1、字符串及数组的操作 字符串截取与拼接
字符串截取:使用 ${变量:起始位置:长度} 进行截取,起始位置:从 0 开始计数。长度:要截取的字符数。 ${变量:offset} 从指定位置到末尾。
字符串拼接:在 Bash 中只需将两个字符串直接放在一起即可
字符串长度:${#string}
#字符串的截取与拼接 string="hello, world" echo "sub string ${string:7:5}" #sub string world echo $(echo $string | cut -d ',' -f 2) #cut截取 world echo ${string: 2} #llo, world echo ${string: -3} #rld 字符串末尾开始计算注意空格 #拼接 只需将两个字符串直接放在一起即可 string1="welcome" echo $string $string1 #hello, world welcome echo ${#string} #12 字符串长度 echo $(whoami) $(date) #命令拼接 数组操作 操作语法示例创建数组array=("apple" "banana" "cherry")访问元素${array[0]}访问所有元素${array[@]}获取数组长度${#array[@]}遍历数组for item in "${array[@]}"; do ... done添加元素array+=("new_item")修改元素array[1]="new_value"删除元素unset array[2]数组切片${array[@]:start:length}关联数组declare -A array; array["key"]="value" #!/bin/bash # 创建数组 fruits=("apple" "banana" "cherry" "date") # 访问数组 echo "First fruit: ${fruits[0]}" echo "All fruits: ${fruits[@]}" echo "Number of fruits: ${#fruits[@]}" # 遍历数组 echo "Fruits:" for fruit in "${fruits[@]}"; do echo "- $fruit" done # 修改数组 fruits[1]="blueberry" fruits+=("elderberry") # 删除元素 unset fruits[2] # 打印修改后的数组 echo "Updated fruits: ${fruits[@]}" # 数组切片 echo "Slice of fruits: ${fruits[@]:1:2}" # 关联数组示例 declare -A colors colors=( ["red"]="apple" ["yellow"]="banana" ["purple"]="grape" ) echo "Colors and fruits:" for color in "${!colors[@]}"; do echo "$color: ${colors[$color]}" done 2、流程控制 循环处理多个文件 #通过循环处理多个文件 files=('f1.txt' "f3.txt" "f2.txt") #files=($(ls *.txt)) for file in "${files[@]}"; do echo "process $file" done #通配符过滤 for file in *.txt; do echo "process $file" done #命令替换 for file in $(find . -name "*.txt"); do echo "process $file" done #递归处理 find . -name "*.txt" | while read file; do echo "process $file" done 条件判断 #条件语句 if [ -e "t.txt" ]; then echo "file exist" else echo "no this file" fi if [ -r "t.txt" ] && [ -w "t.txt" ]; then echo "file can read and wirite" fi echo "请输入一个文件名:" read filename # 使用 if 语句检查文件是否存在 if [ -e "$filename" ]; then echo "文件 $filename 存在。" else echo "文件 $filename 不存在。" fi echo "请输入一个数字(1-3):" read number # 使用 case 语句根据用户输入执行不同操作 case $number in 1) echo "你选择了数字 1" ;; 2) echo "你选择了数字 2" ;; 3) echo "你选择了数字 3" ;; *) echo "无效的选择" ;; esac 3、监控问题 检查服务器的磁盘使用率,并发送告警邮件 #!/bin/bash # 设置阈值(例如:80%) THRESHOLD=80 # 获取磁盘使用率 USAGE=$(df -h / | grep / | awk '{ print $5 }' | sed 's/%//g') # 检查磁盘使用率是否超过阈值 if [ "$USAGE" -gt "$THRESHOLD" ]; then # 设置邮件相关信息 TO="recipient@example " # 收件人邮箱 SUBJECT="磁盘使用率告警" MESSAGE="警告:磁盘使用率已达到 ${USAGE}%,超过设定阈值 ${THRESHOLD}%。请及时处理。" # 发送告警邮件 echo "$MESSAGE" | mail -s "$SUBJECT" "$TO" echo "告警邮件已发送给 $TO" else echo "当前磁盘使用率为 ${USAGE}%,未超过阈值 ${THRESHOLD}%。" fi #使用 df -h / 命令获取根目录的磁盘使用情况。 #使用 grep / 过滤出相关行。 #使用 awk '{ print $5 }' 提取使用率字段(例如 80%)。 #使用 sed 's/%//g' 去掉百分号,得到纯数字。 cpu使用率 #!/bin/bash # 设置监控间隔(单位:秒) INTERVAL=5 # 设置日志文件路径 LOGFILE="/var/log/cpu_usage.log" # 输出脚本开始运行的信息 echo "开始监控 CPU 使用率,间隔时间为 ${INTERVAL} 秒。" echo "监控结果将记录到 ${LOGFILE}。" # 创建或清空日志文件 echo "时间戳, CPU 使用率 (%)" > $LOGFILE # 无限循环监控 CPU 使用率 while true; do # 获取当前时间戳 TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') # 获取 CPU 使用率 CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}') # 输出当前时间和 CPU 使用率 echo "${TIMESTAMP}, ${CPU_USAGE}" | tee -a $LOGFILE # 等待指定的间隔 sleep $INTERVAL done 检测进程状态,失败时重启 #!/bin/bash # 指定要监控的进程名称 PROCESS_NAME="your_process_name" # 指定启动进程的命令 START_COMMAND="your_start_command" # 检查进程是否在运行的函数 check_process() { pgrep -f "$PROCESS_NAME" > /dev/null 2>&1 return $? } # 启动进程的函数 start_process() { echo "启动进程: $PROCESS_NAME" eval "$START_COMMAND &" } # 主循环 while true; do if check_process; then echo "$(date): 进程 $PROCESS_NAME 正在运行" else echo "$(date): 进程 $PROCESS_NAME 停止,正在重启..." start_process fi # 每隔 5 秒检查一次 sleep 5 done 检测特定文本的变化 #!/bin/bash # 要监控的文件 FILE_TO_MONITOR="your_file.txt" # 上一次文件内容的哈希值 LAST_HASH="" # 检查文件是否存在 if [ ! -f "$FILE_TO_MONITOR" ]; then echo "文件 $FILE_TO_MONITOR 不存在。" exit 1 fi # 主循环 while true; do # 计算当前文件内容的哈希值 CURRENT_HASH=$(md5sum "$FILE_TO_MONITOR" | awk '{ print $1 }') # 检查哈希值是否发生变化 if [ "$CURRENT_HASH" != "$LAST_HASH" ]; then echo "$(date): 文件 $FILE_TO_MONITOR 内容发生变化。" LAST_HASH="$CURRENT_HASH" fi # 每隔 5 秒检查一次 sleep 5 done 关键字检测监控 #!/bin/bash # 要监控的文件 FILE_TO_MONITOR="your_file.txt" # 要监控的关键字 KEYWORD="your_keyword" # 检查文件是否存在 if [ ! -f "$FILE_TO_MONITOR" ]; then echo "文件 $FILE_TO_MONITOR 不存在。" exit 1 fi # 主循环 while true; do # 检查文件中是否包含关键字 if grep -q "$KEYWORD" "$FILE_TO_MONITOR"; then echo "$(date): 文件 $FILE_TO_MONITOR 中包含关键字 '$KEYWORD'。" fi # 每隔 5 秒检查一次 sleep 5 done 定时清理临时文件 #!/bin/bash # 清理 /tmp 目录中的临时文件 # 只保留最近 7 天内的文件,其余文件将被删除 find /tmp -type f -mtime +7 -exec rm -f {} \;创建定时任务, crontab -e进入编辑, 在 cron 表中,每一行代表一个定时任务,格式如下:* * * * * command_to_execute
每个星号代表一个时间字段,具体含义如下:
第一个字段:分钟(0-59)第二个字段:小时(0-23)第三个字段:日(1-31)第四个字段:月份(1-12)第五个字段:星期几(0-7),其中 0 和 7 都代表星期天0 6 * * 1 /path/to/your/script.sh 每周一上午 6 点执行
crontab -l查看任务, crontab -r删除所有任务,删除特定的话crontab -e进入编辑删除行
4、top、free、df top命令top命令用于实时显示系统的进程和资源使用情况。它提供了 CPU、内存、进程等信息的动态视图。
top的输出分为两部分:系统信息和进程信息。
系统信息部分(顶部几行):
uptime:系统运行时间。users:当前登录的用户数。load average:系统负载(1分钟、5分钟、15分钟的平均负载)。tasks:当前进程的数量(运行、睡眠、停止等状态)。CPU:各个 CPU 核心的使用情况(用户、系统、空闲等)。Mem:物理内存的使用情况(总量、已用、空闲、缓存等)。Swap:交换空间的使用情况。进程信息部分(下方):
PID:进程 ID。USER:进程所有者。PR:优先级。NI:nice 值。VIRT:虚拟内存使用量。RES:常驻内存使用量。SHR:共享内存使用量。S:进程状态(R:运行,S:睡眠,Z:僵尸等)。%CPU:CPU 使用率。%MEM:内存使用率。TIME+:进程使用的 CPU 时间。COMMAND:进程名称。 free命令free命令用于显示系统的内存使用情况,包括物理内存和交换空间。
输出通常包括以下几列:
total:总内存。used:已用内存。free:空闲内存。shared:共享内存。buff/cache:用于缓存的内存。available:可用内存(包括缓存和缓冲区)。 df命令df命令用于显示文件系统的磁盘空间使用情况,-h选项表示以人类可读的格式显示(自动选择合适的单位)
输出通常包括以下几列:
Filesystem:文件系统的名称。Size:文件系统的总大小。Used:已用空间。Available:可用空间。Use%:已用空间的百分比。Mounted on:挂载点。 5、脚本处理输入参数在 Shell 脚本中处理命令行参数是一个常见的需求。可以使用特殊变量 $1, $2, $3, ... 来访问传递给脚本的参数,$# 用于获取参数的数量,$@ 和 $* 用于获取所有参数。以下是一些基本的用法和示例。
访问命令行参数 $1:第一个参数 $2:第二个参数 $3:第三个参数 ... $#:参数的数量 $@:所有参数(以独立的字符串形式) $*:所有参数(作为一个单一的字符串) #!/bin/bash # 检查参数数量 if [ $# -lt 2 ]; then echo "用法: $0 <参数1> <参数2>" exit 1 fi # 访问参数 PARAM1=$1 PARAM2=$2 echo "第一个参数: $PARAM1" #第一个参数: arg1 echo "第二个参数: $PARAM2" # 第二个参数: arg2 echo "参数总数: $#" #参数总数: 2 # 遍历所有参数 for param in "$@"; do echo "$param" # arg1 arg2 done./script.sh arg1 arg2
处理选项和参数如果你需要处理带有选项的参数(例如 -f 或 --file),可以使用 getopts 命令
#!/bin/bash while getopts "f:n:" opt; do case $opt in f) FILE="$OPTARG" ;; n) NAME="$OPTARG" ;; *) echo "用法: $0 -f <文件> -n <名称>" exit 1 ;; esac done echo "文件: $FILE" echo "名称: $NAME"./script.sh -f file.txt -n JL 输出 文件: myfile.txt 名称: John
6、管道pipline机制及其应用管道(pipeline)是一种强大的机制,用于将一个命令的输出直接传递给另一个命令作为输入。管道的基本语法是使用竖线符号 |,它可以将多个命令串联在一起,从而实现复杂的数据处理和操作。
当你在命令行中使用管道时,Shell 会创建一个进程来执行每个命令,并将它们连接在一起。具体来说,管道的工作机制如下:1)第一个命令的标准输出(stdout)被连接到第二个命令的标准输入(stdin)。2)如果有多个命令,它们会依次连接,形成一个链条。3)每个命令在执行时都是独立的进程,Shell 会管理这些进程的创建和销毁。
列出当前目录下的所有文件,并通过 grep 过滤出以 .txt 结尾的文件 ls -l | grep ".txt"列出当前运行的所有进程,并通过grep过滤出包含 "bash" 的进程: ps aux | grep "bash"cat命令将文件内容输出,wc -l 命令统计行数 cat file.txt | wc -l从file中提取第一列,排序并去重: cat data.txt | awk '{print $1}' | sort | uniq实时监控系统日志,并过滤出包含 "error" 的行 tail -f /var/log/syslog | grep "error"读取csv文件以 , 分割第二列,数值排序到最后一行 cat data.csv | cut -d ',' -f 2 | sort -n | tail -1 7、awk、grep、sed、find、head、tail、tr、cut的使用awk是一个强大的文本处理工具,广泛用于数据提取和报告生成。它可以处理文本文件中的数据,进行模式匹配、字段提取、计算等操作,格式为 awk 'pattern { action }' file
pattern:匹配模式,可以是正则表达式或条件。action:对匹配行执行的操作。file:要处理的文件名。内置变量$0:表示整行文本。$1, $2, ...:表示行中的第一个、第二个、...字段。NR:表示当前行号。NF:表示当前行的字段数。
打印文件所有行awk '{ print }' filename.txt
打印特定字段Alice 25 要打印第二列(年龄),可以使用:awk '{ print $2 }' data.txt
要打印文件中的第 1 行和第 3 行, awk 'NR==1 || NR==3' data.txt (NR 是内置变量,表示当前行号) ; awk '/Alice/' data.txt 模式查找
条件筛选打印第二列且年龄大于20的行 awk '$2 > 20' data.txt 计算和,第一列是数字: awk '{ sum += $1 } END { print sum }' numbers.txt格式输出awk '{ printf "Name: %s, Age: %d\n", $1, $2 }' data.txt多文件处理awk '{ print FILENAME ": " $0 }' f1.txt f2.txt 打印每个文件的内容并在每行前加上文件名 grep:文本搜索工具用于在文件或标准输入中搜索匹配指定模式的行。
常用选项-i:忽略大小写。 -v:反向匹配,输出不匹配的行。
-r:递归搜索目录中的文件。 -E:启用扩展正则表达式(ERE)。
-o:只输出匹配的部分。 -n:显示匹配行的行号。
grep "error" log.txt # 搜索包含 "error" 的行 grep -i "error" log.txt # 忽略大小写搜索 grep -r "error" /var/log/ # 递归搜索目录中的文件 # 使用正则表达式搜索 grep -E "[0-9]{3}-[0-9]{2}-[0-9]{4}" data.txt sed流编辑器用于对文本进行查找、替换、插入、删除等操作,支持正则表达式。
常用选项s/regex/replacement/:替换匹配的内容。 -i:直接修改文件内容。
-n:禁止自动输出,通常与 p 命令一起使用。p:打印匹配的行。 d:删除匹配的行。
sed 's/foo/bar/' file.txt # 替换文件中的 "foo" 为 "bar" sed 's/foo/bar/g' file.txt # 全局替换 sed -i 's/foo/bar/g' file.txt # 直接修改文件 sed '/^$/d' file.txt # 删除空白行 sed -n '/error/p' log.txt # 打印匹配的行 find文件查找工具用于在目录树中查找文件,并可以对找到的文件执行操作。
常用选项-name:按文件名查找。 -type:按文件类型查找(f 表示文件,d 表示目录)
-mtime:按修改时间查找。 -exec:对找到的文件执行命令。-size:按文件大小查找。
find . -name "*.txt" # 查找当前目录下的所有 .txt 文件 find . -size +1M # 查找大于 1MB 的文件 # 查找并删除 7 天前的日志文件 find /var/log -name "*.log" -mtime +7 -exec rm {} \; find . -name "*.jpg" -exec gzip {} \; # 查找并压缩所有 .jpg 文件 工具主要用途特点适用场景grep文本搜索快速搜索匹配的行,支持正则表达式查找日志、过滤文本sed文本编辑流式编辑,支持查找、替换、插入、删除批量替换文本、删除或修改特定行awk文本处理强大的字段处理能力,支持编程处理结构化文本(如 CSV)、数据统计find文件查找在目录树中查找文件,支持条件过滤和执行命令查找文件、批量操作文件 tail 命令tail 命令用于显示文件的末尾部分,默认显示最后10行。
常用选项: -n <行数>:指定显示的行数。例如,tail -n 20 file.txt 显示文件的最后20行-f:实时跟踪文件的新增内容,常用于查看日志文件。例如,tail -f logfile.log-c <字节数>:显示文件的最后若干字节。例如,tail -c 100 file.txt 显示文件的最后100字节 head命令head命令用于显示文件的开头部分,默认显示前10行。
常用选项:-n <行数>:指定显示的行数。例如,head -n 20 file.txt 显示文件的前20行。
-c <字节数>:显示文件的前若干字节。例如,head -c 100 file.txt 显示文件的前100字节。
tr 命令tr 命令用于转换或删除字符。它通常用于处理文本流。
常用选项: -d:删除字符。例如,tr -d 'a' 删除所有 a 字符; tr -d '0-9' < file.txt # 删除文件中的所有数字-s:压缩重复字符。例如,tr -s ' ' 将多个连续空格压缩为一个空格 tr 'a-z' 'A-Z' < file.txt # 将文件中的所有小写字母转换为大写字母-c:补集操作,表示对不在指定字符集中的字符进行操作 echo "hello world" | tr -s ' ' # 将多个连续空格压缩为一个空格 cut命令cut命令用于从文件的每一行中提取部分内容。它可以根据字段、字符位置或字节位置进行提取。
常用选项:-d:指定字段分隔符,默认是制表符。eg: 提取文件的第一列(假设列以空格分隔) cut -d ' ' -f 1 file.txt
-f: 指定要提取的字段。eg、提取文件的第1和第3列(假设列以逗号分隔) cut -d ',' -f 1,3 file.csv
-c: 按字符位置提取。提取每行的第1到第5个字符 cut -c 1-5 file.txt
-b: 按字节位置提取。提取每行的第1到第5个字节 cut -b 1-5 file.txt 综合例子 查找日志文件中的错误并统计 # 查找 /var/log 目录下所有 .log 文件 find /var/log -name "*.log" -type f | while read file; do # 使用 grep 查找包含 "error" 的行 grep "error" "$file" | sed 's/error/ERROR/g' > "${file}.errors" # 使用 awk 统计错误行数 error_count=$(awk '/ERROR/ { count++ } END { print count }' "${file}.errors") echo "File: $file, Errors: $error_count" done 输出文本第十行 #1、awk 实现 awk "NR==10" file.txt #2、tail 结合head tail -n +10 file.txt | head -1 #从第10行开始 #3、sed -n选项取消sed默认的输出,'10p'指定只打印第10行 sed -n '10p' file.txt #基本操作 cnt=0 while read line && [ $cnt -le 10 ]; do let 'cnt = cnt + 1' # cnt=$((cnt + 1)) if [ $cnt -eq 10 ]; then echo $line exit 0 fi done < file.txt 统计词频 cat words.txt| tr -s ' ' '\n' | sort | uniq -c | sort -r | awk '{print $2, $1}'上一篇
SQL经典题型
下一篇
stm32week5