当前位置: 首页 > news >正文

shell场景题

目录

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.com"  # 收件人邮箱
    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}'

    相关文章:

  • 通往 AI 之路:Python 机器学习入门-语法基础
  • 基于51单片机超声波测量报警LCD1602显示( proteus仿真+程序+设计报告+讲解视频)
  • 塔子哥Python算法基础课
  • Conda 环境搭建实战:从基础到进阶
  • flutter AnimationController 动画使用总结
  • [创业之路-329]:华为铁三角实施的步骤
  • uiautomatorviewer定位元素报Unexpected ... UI hierarchy
  • stm32week5
  • 细说 Java 集合之 Map
  • 【机器学习chp10】降维——(核化)PCA + MDS + lsomap + 拉普拉斯特征映射 + t-NSE + UMAP
  • 【无标题】词源故事:role与roll的联系,词根horr(恐惧)与hair(毛发)关系
  • Python之参数星号(*)使用笔记
  • js基础二
  • JMeter 实战项目脚本录制最佳实践(含 BadBoy 录制方式)
  • Docker 常用指令手册(学习使用)
  • Skywalking介绍,Skywalking 9.4 安装,SpringBoot集成Skywalking
  • 16.11 LangChain SQL 生成与执行实战:构建安全高效的数据库查询引擎
  • DeepSeek如何快速开发PDF转Word软件
  • 【JAVA面试题】JDK、JRE、JVM 三者区别和联系
  • 商米科技前端工程师(base上海)内推
  • 这个死亡率第一的“老年病”,正悄悄逼近年轻人
  • 取得金奖西瓜品种独家使用权的上海金山,为何要到异地“试种”?
  • 复旦大学艺术馆开馆:以当代视角再看文科文脉
  • 肖钢:一季度证券业金融科技投资强度在金融各子行业中居首
  • 光速晋级!2025年多哈世乒赛孙颖莎4比0战胜对手
  • 侵害孩子者,必严惩不贷!3名性侵害未成年人罪犯被执行死刑