shell脚本基础练习

        这是我在学习shell脚本时整理的常见练习题,大家可按照顺序来练习,语法都是从前往后逐渐递进的,另外看不懂的建议用AI分析,希望对大家有帮助!

目录

1.判断是否已经成功挂载光盘,如果挂载则显示光盘中的文件

2.编写脚本,判断当前的系统剩余内存的大小,如果小于 600M 则输出信息到日志文件中

3.编写脚本,判断当前脚本的执行者是否为 root 用户

4.判断光盘是否挂载,如果挂载则显示挂载目录下的内容,否则执行挂载命令

5.判断本地仓库是否创建,如果创建则显示已创建,否则创建这个本地仓库文件。

6.判断 sshd 进程是否运行,如果服务未启动则启动相应服务。

7.检查主机是否存活,并输出结果

8.接收两个整数并比较其大小。

9.根据用户的输入成绩,判断优良中差。

10.由用户从键盘输入一个字符,判断该字符是字母还是数字,以及其他字符,并输出相应的提示信息。

11.9题用case实现

12.开发一个 rsync 起停脚本

13.直接列出列表的所有元素

14.seq

15.循环输出1-10中的奇数

16.获取根目录下所有文件名作为变量的值打印输出。

17.打印出如下的语句中字符数不大于6的单词。

18.循环输入所有的参数

19.批量创建用户

20.循环输出 1~10这几个数

21.使用 exec 读取指定文件的内容并循环输出。文件的内容如下

22.猜商品价格。

23.使用while读取文件,文件的内容如下

24.until循环输出0~10之间的数

25.用until实现将之前使用 for 循环语句创建的 test01 - test30 用户删除

26.select实现mysql版本的选择

27.用select实现选择水果,假设我们有如下水果可供选择:

28.打印九九乘法表

29.打印三角形

30. 使用case实现成绩优良差的判断

31.for ping测试指网段的主机

32.计算两个参数的和

33.获取字符串的长度

34.将一个点分十进制格式的IP地址转换成点分二进制格式。

35.写一个脚本,判断给定的 IP 地址范围[192.168.72.130 ~ 192.168.72.140]是否在线。

36.两数相加

37.根据用户输入的数值计算该数的阶乘

38.编写一个bash脚本以输出一个文本文件mywords.txt中第5行的内容。

39.使用函数递归/var/log目录,如果是文件直接输入文件名,如果是目录则输出目录名称并输出目录下所有子目录和文件名

40.数组遍历指定的目录

41.从标准输入读取 n 次字符串,每次输入的字符串保存在数组 array 中。

42.将字符串中的字母逐个放入数组,并输出到标准输出

43.把1~3这3个数字存到数组中,分别乘以8后再依次输出

44.输出如下内容中字母数不大于6的单词。

45.写一个bash脚本以统计一个文本文件nowcoder.txt 中每个单词出现的个数。

46.监控cpu使用率的脚本


1.判断是否已经成功挂载光盘,如果挂载则显示光盘中的文件

#!/bin/bash
# 获取 /mnt 目录下文件列表的行数
num=$(ls -l /mnt | grep "total" | cut -d" " -f2)
# 判断行数是否为 0,如果是则说明光盘未挂载
if [ $num -eq 0 ] ; then
        echo 'no mount'
else
        # 显示 /mnt 目录中的文件列表
        ls -l  /mnt
fi

2.编写脚本,判断当前的系统剩余内存的大小,如果小于 600M 则输出信息到日志文件中

#!/bin/bash
# 1.使用 free 命令获取系统内存信息,
   2.然后使用 grep 命令过滤出包含 "Mem:" 的行,
   3.再使用 tr 命令将连续的空格字符压缩为单个空格字符,
  4.最后使用 cut 命令提取第 4 列的剩余内存值(以兆字节为单位)并赋值给变量 free_mem
free_mem=$(free -m | grep "Mem:" | tr -s " " | cut -d " " -f4)
# 检查剩余内存是否小于 600 兆字节
if [ $free_mem -lt 600 ]; then
    # 如果剩余内存小于 600 兆字节,则记录日志
    logger "free mem less 600M"
fi

3.编写脚本,判断当前脚本的执行者是否为 root 用户
 

#!/bin/bash
# 检查当前登录用户是否为 root 用户
# 如果不是 root 用户,则输出提示信息
if [ $USER != "root" ]; then
    echo "Use root to login"
fi

4.判断光盘是否挂载,如果挂载则显示挂载目录下的内容,否则执行挂载命令

#!/bin/bash
# 获取 /mnt 目录下以 "总用量" 开头的文件的第二列的值,并将其赋给 number 变量
number=$(ls /mnt | grep "总用量" | cut -d " " -f2)
# 检查 number 变量是否为 0
if [[ $number -eq 0 ]]; then
    # 如果 number 变量为 0,则将光盘挂载到 /mnt 目录下
    mount /dev/sr0 /mnt
else
    # 如果 number 变量不为 0,则列出 /mnt 目录下的文件列表
    ls /mnt
fi

5.判断本地仓库是否创建,如果创建则显示已创建,否则创建这个本地仓库文件。

#!/bin/bash
# 通过判断所有仓库中是否存在baseurl=/mnt的项,来认定本地仓存是否存在
# 使用 cat 命令读取所有仓库配置文件,并通过 grep、tail 和 cut 命令获取最后一个仓库的 baseurl 内容
res=$(cat /etc/yum.repos.d/*.repo | grep "baseurl" | tail -1 | cut -d"=" -f2)

# 检查获取到的 baseurl 是否为 /mnt
if [ "$res" == "/mnt" ]; then
    echo "Local repository already exists."
else
    echo "Creating local repository..."

    # 使用 cat 命令将 YUM 仓库配置写入到 yum.repo 文件
    /usr/bin/cat > /etc/yum.repos.d/yum.repo << "EOF"
    [baseOS]
    name=baseOS
    baseurl=/mnt
    gpgcheck=0
    EOF

    echo "Local repository created successfully."
fi

6.判断 sshd 进程是否运行,如果服务未启动则启动相应服务。

方式一:服务状态实现
#!/bin/bash

# 检查sshd服务的状态
sshd_status=$(systemctl is-active sshd)

# 如果sshd服务处于活跃状态
if [ "$sshd_status" == "active" ]; then
    echo "sshd已激活"
else
    # 如果sshd服务未激活,则启动它
    echo "sshd未激活"
    systemctl start sshd
    echo "sshd已启动"
fi



方式二:
#!/bin/bash
# 通过检查网络状态,查看端口22是否在使用,以确定sshd是否正在运行
sshd_port_count=$(netstat -lnput | grep 22 | wc -l)

# 如果在端口22上找到相关的网络活动,表示sshd正在运行
if [ $sshd_port_count -gt 0 ]; then
    echo "sshd已激活"
else
    # 如果未找到端口22上的活动,表示sshd可能没有运行,需要启动
    echo "sshd未激活"
    systemctl start sshd  # 尝试启动sshd服务
    echo "sshd已启动"
fi


7.检查主机是否存活,并输出结果

#!/bin/bash
# 定义要 ping 的主机 IP 地址
host="192.168.145.146"
# 使用 ping 命令发送 3 个数据包到指定的主机 IP,设置超时时间为 1 秒,并将所有输出重定向到 /dev/null(即丢弃输出)
ping -c 3 -W 1 $host &> /dev/null
# 检查 ping 命令的退出状态码($?)是否为 0,如果是则表示主机可达,否则表示不可达
if [ $? -eq 0 ]; then
    echo "$host is active"  # 输出主机活跃的消息
else
    echo "$host is not active"  # 输出主机不活跃的消息
fi

8.接收两个整数并比较其大小。

方式一:read实现
#!/bin/bash
# 提示用户输入两个数字,并将输入的数字保存到变量 num1 和 num2 中
read -p "please input two numbers: " num1 num2

# 使用 if-elif-else 结构比较输入的两个数字
if [ $num1 -eq $num2 ]; then                    # 检查 num1 是否等于 num2
    echo "$num1 == $num2"                        # 如果相等,则输出相等的消息
elif [ $num1 -gt $num2 ]; then                 # 如果 num1 大于 num2
    echo "$num1 > $num2"                         # 则输出 num1 大于 num2 的消息
elif [ $num1 -lt $num2 ]; then                 # 如果 num1 小于 num2
    echo "$num1 < $num2"                         # 则输出 num1 小于 num2 的消息
else                                            # 如果以上条件都不满足
    echo "number error"                          # 则输出数字错误的消息
fi



方式二:脚本传参实现
#!/bin/bash
# 检查脚本是否接收了两个参数
if [ $1 -eq $2 ]; then                        # 检查第一个参数是否等于第二个参数
    echo "$1 == $2"                            # 如果相等,则输出相等的消息
elif [ $1 -gt $2 ]; then                      # 如果第一个参数大于第二个参数
    echo "$1 > $2"                             # 则输出第一个参数大于第二个参数的消息
elif [ $1 -lt $2 ]; then                      # 如果第一个参数小于第二个参数
    echo "$1 < $2"                             # 则输出第一个参数小于第二个参数的消息
else                                          # 如果以上条件都不满足
    echo "error"                               # 则输出错误消息
fi

9.根据用户的输入成绩,判断优良中差。


85-100 为优,A
70-84 为良,B
60-69 为合格,C
60以下为不合格,D

方式一:[[  ]]结合&&,||实现
#!/bin/bash
# 提示用户输入成绩并保存到变量score中
read -p "input score:" score
# 检查分数是否为空
if [[ -z $score ]]; then
    echo "the score is not empty"
    exit 1
# 检查分数是否在有效范围内(0到100之间)
elif [[ $score -gt 100 || $score -lt 0 ]];then
    echo "the score should be between 0 and 100, please input a correct score"
    exit 2
# 判断成绩所属等级并输出对应的评语
elif [[ $score -ge 85 && $score -le 100 ]]; then
    echo "A 优"
elif [[ $score -ge 70 && $score -le 84 ]]; then
    echo "B 良"
elif [[ $score -ge 60 && $score -le 69 ]]; then
    echo "C 合格"
else
    echo "D 不合格"
fi


方式二:[ ]结合-a,-o实现
#!/bin/bash
# 提示用户输入成绩并保存到变量score中
read -p "input score:" score
# 检查分数是否为空
if [ -z $score ]; then
    echo "the score is not empty"
    exit 1
# 检查分数是否在有效范围内(0到100之间)
elif [ $score -gt 100 -o $score -lt 0 ];then
    echo "the score should be between 0 and 100, please input a correct score"
    exit 2
# 根据分数判断等级并输出对应的评语
elif [ $score -ge 85 -a $score -le 100 ]; then
    echo "A 优"
elif [ $score -ge 70 -a $score -le 84 ]; then
    echo "B 良"
elif [ $score -ge 60 -a $score -le 69 ]; then
    echo "C 合格"
else
    echo "D 不合格"
fi

10.由用户从键盘输入一个字符,判断该字符是字母还是数字,以及其他字符,并输出相应的提示信息。
 

#!/bin/bash
# 提示用户输入一个字符并保存到变量key中
read -p "input a key:" key
# 检查输入是否为空
if [ -z $key ]; then
    echo "not null"
    exit 1
fi
# 检查输入字符长度是否为1
if [ $(expr length $key) -ne 1 ]; then
    echo "char must be one"
    exit 2
fi
# 根据输入字符的类型进行分类并输出对应的信息
case $key in
    [0-9])
        echo "number"
        ;;
    [a-z]|[A-Z])
        echo "char"
        ;;
    *)
        echo "other"
        ;;
esac

11.9题用case实现

#!/bin/bash
# 提示用户输入一个分数并保存到变量score中
read -p "input score:" score
# 使用 case 语句根据分数范围输出对应的等级
case $score in
    # 如果分数在 85 到 100 之间,输出 A
    [8][5-9]|[9][0-9]|100)
        echo "A"
        ;;
    # 如果分数在 70 到 84 之间,输出 B
    [7][0-9]|[8][0-4])
        echo "B"
        ;;
    # 如果分数在 60 到 69 之间,输出 C
    [6][0-9])
        echo "C"
        ;;
    # 其他分数,输出 D
    *)
        echo "D"
esac

12.开发一个 rsync 起停脚本

#!/bin/bash
# 检查参数数量是否正确
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 {start|stop|restart}"
    exit 0
fi
# 根据参数执行相应操作
case $1 in
    "start")
        # 启动rsync服务
        /usr/bin/rsync --daemon
        sleep 1
        # 检查rsync服务是否成功启动
        if [ $(ss -lntup | grep rsync | wc -l) -ge 1 ]; then
            echo "rsync started"
            exit 0
        fi
        ;;
    "stop")
        # 停止rsync服务
        killall rsync &>/dev/null
        sleep 1
        # 检查rsync服务是否成功停止
        if [ $(ss -lntup | grep rsync | wc -l) -eq 0 ]; then
            echo "rsync stopped"
            exit 0
        fi
        ;;
    "restart")
        # 重启rsync服务
        if [ $(ss -lntup | grep rsync | wc -l) -ge 1 ]; then
            killall rsync &>/dev/null
            /usr/bin/rsync --daemon
            sleep 1
            echo "rsync restarted"
        else
            echo "rsync is not running, starting..."
            /usr/bin/rsync --daemon
            sleep 1
            echo "rsync started"
        fi
        exit 0
        ;;
    *)
        # 参数错误提示
        echo "Usage: $0 {start|stop|restart}"
        exit 0
        ;;
esac



13.直接列出列表的所有元素

#!/bin/bash
# 这行指定了将执行此脚本的解释器,这里是bash。
# 循环遍历列表中的每个IP地址
for var in 192.168.132.130 192.168.132.131 192.168.132.132
do
        # 打印当前的IP地址
        echo $var
done
# 循环结束


改进版本1:通过{..}实现
#!/bin/bash
# 指定脚本解释器为bash
# 使用花括号扩展生成从192.168.132.130到192.168.132.132的IP地址列表
# {0..2} 表示从0到2的数字序列,会替换成列表中的每个数字
for var in 192.168.132.13{0..2}
do
        # 打印当前的IP地址
        echo $var
done
# 循环结束


改进版2:通过seq实现
#!/bin/bash
# 指定脚本解释器为bash
# 使用seq命令生成从0到2的数字序列,并利用格式字符串生成IP地址列表
# 这里的格式字符串 "192.168.132.13%1g" 中的 %1g 会被0到2的数字替换
# 生成的IP地址列表为:192.168.132.130、192.168.132.131、192.168.132.132
for var in `seq -f "192.168.132.13%1g" 0 2`
do
        # 打印当前的IP地址
        echo $var
done
# 循环结束

14.seq

# 生成一个带有格式的序列,使用 seq 命令
# -f 参数指定了格式字符串,这里的 %1g 表示按照给定的数字进行格式化
# 生成的序列为:192.168.132.130
seq -f "192.168.132.13%1g"

# 生成从 1 到 100 的数字序列,使用 seq 命令,并将数字以加号连接
# 然后使用 bc 命令计算这个序列的总和
seq -s"+" 1 100 | bc


# 使用 seq 命令生成一个序列,从 2 开始,以步长 2 递增,直到 100 结束,并用加号分隔
# 生成的序列为:2+4+6+...+98+100
seq -s"+" 2 2 100 | 
# 将生成的序列传递给 bc 命令进行求和计算
bc

通过for实现100以内的偶数求和
#!/bin/bash
sum=0
for ((i=2;i<=100;i+=2))
do
        let sum+=i
done
echo $sum

15.循环输出1-10中的奇数

#!/bin/bash
# 以上一行声明脚本解释器为 bash

# 使用for循环遍历从1到10的数字,步长为2,即遍历奇数
for var in {1..10..2}
do
    # 打印当前迭代的数字
    echo $var
done

16.获取根目录下所有文件名作为变量的值打印输出。

#!/bin/bash
# 以上一行声明脚本解释器为 bash

# 使用 for 循环遍历根目录下的所有目录
# `ls -F /`:列出根目录下的所有文件和目录,并在每个目录名称后面加上斜杠以区分目录和文件
# `grep "/$"`:过滤出以斜杠结尾的行,即目录行
for file in `ls -F / | grep "/$"`
do
    # 打印每个目录的名称
    echo $file
done



17.打印出如下的语句中字符数不大于6的单词。

hello world rabbit favorite eat apple cabbage

#!/bin/bash
# 以上一行声明脚本解释器为 bash

# 使用for循环遍历单词列表
for word in hello world rabbit favorite eat apple cabbage
do
    # 判断单词的长度是否小于等于6
    if [ `expr length $word` -le 6 ]; then
        # 如果单词长度小于等于6,则打印该单词
        echo $word
    fi
done

18.循环输入所有的参数

#!/bin/bash
# 以上一行声明脚本解释器为 bash

# 使用for循环遍历命令行参数列表中的每个参数
for var in $@
do
    # 打印每个参数的值
    echo $var
done

19.批量创建用户

用户名以 test 开头,按数字序号变化。一共添加 30 个账号,名称如:test01、test02、...、test10、....test30
 

#!/bin/bash
# 循环创建用户
for ((i=1;i<=30;i++))
do
    # 根据循环计数器 i 的值确定用户名
    if [ $i -lt 10 ]; then
        user=test0$i
    else
        user=test$i
    fi
    # 检查用户是否存在
    if ! id -u $user &>/dev/null; then
        # 如果用户不存在,则创建用户并设置密码
        useradd $user
      # 通过管道将密码 "Abc123456" 传递给 passwd 命令,用于为新创建的用户设置密码
      echo "Abc123456" | passwd --stdin $user &>/dev/null
    else
        # 如果用户已存在,则输出提示信息
        echo "$user already exists"
    fi
done


方式二:通过seq实现
#!/bin/bash
# 循环遍历生成 test01 到 test30 的用户名
for u in `seq -f "test%02g" 1 30`
do
    # 检查用户是否已存在
    if ! id -u $u &>/dev/null; then
        # 如果用户不存在,则创建用户
        useradd $u
        # 使用 echo 和管道将密码传递给 passwd 命令,并将标准输出和标准错误输出都重定向到 /dev/null,确保密码设置过程中的安全
        echo "Abc123456" | passwd --stdin $u &>/dev/null
    fi
done

20.循环输出 1~10这几个数

#!/bin/bash
# 设置初始变量 i 为 1
i=1
# 开始 while 循环,循环条件是 i 小于等于 10
while [ $i -le 10 ]
do
    # 打印当前 i 的值
    echo $i
    
    # 将 i 的值加 1
    let i++
done

21.使用 exec 读取指定文件的内容并循环输出。文件的内容如下
 

```bash
[root@openEuler ~]# cat myfile
open
openlab
openlab123
linux
readhat
```
 

方式一:
#!/bin/bash
# 将文件 "myfile" 的内容作为标准输入传递给脚本
exec < myfile
# 开始 while 循环,逐行读取文件中的内容
while read line
do
    # 打印当前行的内容
    echo $line
done



方式二:
#!/bin/bash
# 使用重定向将文件 "myfile" 的内容作为输入传递给 while 循环
while read line
do
    # 打印当前行的内容
    echo $line
done < myfile

22.猜商品价格。

通过变量 RANDOM 来获取随机的价格,然后提示用户猜价格,并记录次数,猜中退出,或次数达到 5 也退出。
 

#!/bin/bash
# 获取随机价格
random_price=$((RANDOM % 100 + 1))  # 生成1到100之间的随机数作为价格
# 记录次数
count=0
while :
do
    # 提示用户输入
    read -p "please input your price:" price
    ((price = price))  # 将输入的价格转换为数字格式
    let count++  # 次数加1
    # 判断是否猜中或次数达到五次退出
    if [ $random_price -eq $price -o $count -ge 5 ]; then
        break  # 若猜中或者猜了五次,退出循环
    elif [ $price -gt $random_price ]; then
        echo "your price is high"
        continue  # 若价格过高,继续下一轮循环
    else
        echo "your price is low"
        continue  # 若价格过低,继续下一轮循环
    fi
done

23.使用while读取文件,文件的内容如下


```
192.168.72.131  22
192.168.72.132  23
192.168.72.133  22
```

执行输出的结果为:

```
IP: 192.168.72.131, PORT: 22
IP: 192.168.72.132, PORT: 23
IP: 192.168.72.133, PORT: 22
```

#!/bin/bash
# 从文件 ipf 逐行读取内容并处理
while read line
do
    # 从每行内容中提取 IP 地址和端口号
    IP=`echo $line | cut -d" " -f1`
    PORT=`echo $line | cut -d" " -f2`
    # 输出 IP 地址和端口号
    echo "IP: $IP, PORT: $PORT"
done < ipf  # 从文件 ipf 中读取数据



24.until循环输出0~10之间的数

#!/bin/bash
# 设置初始值为0
i=0
# 使用 until 循环,直到 i 大于 10 才结束
until [ $i -gt 10 ]
do
    # 输出当前 i 的值
    echo $i
    # 将 i 值加1
    let i+=1
done

这里 let i+=1<==>((i+=1))

25.用until实现将之前使用 for 循环语句创建的 test01 - test30 用户删除

#!/bin/bash
# 设置初始值为1
i=1
# 使用 until 循环,直到 i 大于 30 才结束
until [ $i -gt 30 ] 
do
    # 根据循环计数器 i 的值确定用户名
    if [ $i -lt 10 ]; then
        user=test0$i
    else
        user=test$i
    fi
    # 检查用户是否存在
    if id -u $user &>/dev/null; then
        # 如果用户存在,则删除
        userdel -r $user
    else
        # 否则输出用户不存在
        echo "$user does not exist"
    fi
    # 将 i 值加1
    let i++
done

26.select实现mysql版本的选择

#!/bin/bash
# 使用 select 构建菜单,供用户选择 MySQL 版本
select mysql_version in 5.6 5.7 8.0
do
    # 输出用户选择的 MySQL 版本
    echo $mysql_version
done

27.用select实现选择水果,假设我们有如下水果可供选择:

Apple,  Banana, Pear, Watermelons, Grape

#!/bin/bash
# 使用 select 构建菜单,供用户选择喜欢的水果
select fruit in Apple Banana Pear Watermelons Grape
do
    # 输出用户选择的水果
    echo "你最喜欢的水果是 $fruit"
    # 跳出循环
    break
done

28.打印九九乘法表

#!/bin/bash
# 外层循环,控制乘法表的行数
for i in {1..9}; do
    # 内层循环,控制乘法表的列数
    for j in {1..9}; do
        # 仅当列数小于等于行数时,才进行乘法运算和输出
        if [ $j -le $i ]; then
            # 输出乘法表格,并计算乘积
            echo -n "$i*$j = `expr $i \* $j` "
        fi
    done
    # 输出换行,开始新的一行乘法表
    echo ""
done

29.打印三角形

#!/bin/bash
# 外层循环,控制行数
for i in {1..9}; do
    # 内层循环,输出每行前面的空格,用于形成倒三角形
    for ((col=1; col<=10-i; col++)); do
        echo -n " "  # 输出空格
    done
    # 内层循环,输出每行的数字
    for ((k=1; k<=i; k++)); do
        echo -n "$i"  # 输出当前行数
    done
    echo " "  # 输出换行,开始新的一行
done

30. 使用case实现成绩优良差的判断

read -p "please input your score:" score
case $score in
        [9][0-9]|100)
                echo "优秀"
                ;;
        [8][0-9])
                echo "良好"
                ;;
        [6][0-9]|[7][0-9])
                echo "中等"
                ;;
        *)
                echo "不及格"
                ;;
esac

31.for ping测试指网段的主机

 网段由用户输入,例如用户输入192.168.2 ,则ping 192.168.2.10 --- 192.168.2.20
   UP: /tmp/host_up.txt
   Down: /tmp/host_down.txt
 

#!/bin/bash
# 提示用户输入 IP 地址的最后一部分
read -p "请输入 IP 地址的最后一部分:" net
# 循环遍历给定范围内的 IP 地址
for i in {10..20}
do
    # 拼接完整的 IP 地址
    ip="$net.$i"

    # ping IP 地址
    ping -c 1 $ip > /dev/null
    # 检查 ping 命令的返回值,0 表示成功,非 0 表示失败
    if [ $? -eq 0 ]; then
        # 追加记录到 host_up.txt 文件中
        echo "$ip" >> /tmp/host_up.txt
    else
        # 追加记录到 host_down.txt 文件中
        echo "$ip" >> /tmp/host_down.txt
    fi
done

32.计算两个参数的和
 

#!/bin/bash

# 定义一个名为sum1的函数,用于计算两个数字的和
sum1() {
    sum=$[$1 + $2]  # 计算两个数字的和
    echo $sum  # 输出计算结果
}

# 从用户输入获取第一个数字
read -p "请输入第一个数字:" first
# 从用户输入获取第二个数字
read -p "请输入第二个数字:" second

# 调用sum1函数并传入用户输入的数字作为参数,但实际上传入的是字符串 "first" 和 "second",而不是变量的值
sum1 first second
# 或者
# 将sum1函数的输出保存到变量res中(这里的调用方式也是错误的,应该是将变量值传递给函数)
res=$(sum1 first second)

# 输出sum1函数的结果
echo $res

33.获取字符串的长度

#!/bin/bash

# 定义名为length的函数,用于计算字符串的长度
length() {
    str=$1  # 将第一个参数赋值给变量str,即要计算长度的字符串
    len=0  # 初始化长度为0

    # 如果传入的字符串不为空,则计算其长度
    if [ "$1" != "" ]; then
        len=${#str}  # 使用${#str}来获取字符串的长度
    fi

    # 将计算得到的长度作为返回值
    return $len
}

# 调用length函数并传入字符串"abc123"作为参数,但是在脚本中并没有正确获取函数的返回值
length "abc123"

# 输出函数的返回值(但是这里的输出方法是错误的,应该使用$?来获取函数的返回值)
echo "字符串的长度为 $?"

34.将一个点分十进制格式的IP地址转换成点分二进制格式。

比如 255.255.255.255   -->  11111111.11111111.11111111.11111111
 

#!/bin/bash

# 定义一个名为ip_switch_bin的函数,用于将IP地址的每一部分转换为二进制表示
ip_switch_bin(){
        ip=$1  # 将传入的第一个参数(IP地址)赋值给变量ip
        # 使用awk将IP地址分割为四个数字,每个数字以点(.)为分隔符
        ips=$(echo $ip | awk 'BEGIN{RS="."} print{}')
        res=""  # 初始化结果变量

        # 遍历ips数组中的每个元素
        for i in ${ips[@]}
        do
                # 将每部分的IP地址转换为二进制并追加到结果字符串res中
                # 注意:这里的表达式应该是res+=$(echo "obase=2;$i" | bc),当前写法有语法错误
                res+="obse=2;$i"|bc     
        done
        echo $res  # 输出最终的结果
}

# 调用ip_switch_bin函数,并将192.168.123.12作为参数传递
resbin=$(ip_switch_bin 192.168.123.12)
# 将结果按空格分割并用点(.)重新连接输出
echo $resbin | xargs echo | tr ' ' '.'

35.写一个脚本,判断给定的 IP 地址范围[192.168.72.130 ~ 192.168.72.140]是否在线。
 

#!/bin/bash

# 定义名为online的函数,用于检查指定IP范围内的主机是否在线
online() {
    # 使用循环迭代指定的IP范围
    for i in {148..152}
    do
        # 使用ping命令检查当前IP地址是否能够连通,并将输出重定向到/dev/null以隐藏输出信息
        if ping -c1 192.168.72.$i &>/dev/null; then
            # 如果ping命令成功,说明主机在线,打印提示信息
            echo "192.168.72.$i is up"
        else
            # 如果ping命令失败,说明主机不在线,打印提示信息
            echo "192.168.72.$i is unknown"
        fi
    done
}

# 调用online函数,开始检查主机在线状态
online

36.两数相加

#!/bin/bash

a=1  # 设置变量a的值为1
b=2  # 设置变量b的值为2

#c=$((a+b))   # 使用$(( ))语法计算a和b的和,并将结果赋值给变量c(已注释掉)
#let c=a+b    # 使用let命令计算a和b的和,并将结果赋值给变量c(已注释掉)
#c=`expr $a + $b`  # 使用expr命令计算a和b的和,并将结果赋值给变量c(已注释掉)

echo $c  # 输出变量c的值(但是在脚本中未定义c,因此这里将输出空白)

37.根据用户输入的数值计算该数的阶乘

#!/bin/bash
# 定义递归函数,计算给定数值的阶乘
# 参数: $1 - 要计算阶乘的数值
# 返回值: 无
recursion() {
    # 如果输入值为1,阶乘为1
    if [ $1 -eq 1 ]; then
        return 1
    # 如果输入值大于1,使用递归计算阶乘
    elif [ $1 -gt 1 ]; then
        local n=$(($1-1))
        recursion $n  # 递归调用函数
        let res=$1*$?  # 计算阶乘结果
    # 输入值无效
    else
        echo "error res"
    fi
    return $res  # 返回阶乘结果
}

recursion 5  # 调用递归函数计算阶乘
echo $?  # 打印阶乘结果

38.编写一个bash脚本以输出一个文本文件mywords.txt中第5行的内容。

假设 mywords.txt 内容如下:
welcome
to
nowcoder
this
is
shell
code
你的脚本应当输出:is
 

#!/bin/bash

# 使用sed命令从文件mywords.txt中提取第5行的内容,并将结果赋值给变量res
res=`cat mywords.txt | sed -n "5p"`

# 输出变量res的值
echo $res

39.使用函数递归/var/log目录,如果是文件直接输入文件名,如果是目录则输出目录名称并输出目录下所有子目录和文件名
 

#!/bin/bash

# 定义名为list_file的函数,用于递归遍历指定目录下的文件和子目录
list_file() {
	for f in $(ls $1)  # 循环遍历指定目录下的所有文件和目录
	do
		if [ -d "$1/$f" ]; then  # 如果当前项是一个目录
			echo "$2 directory $f"  # 输出目录信息
			list_file "$1/$f" "├── $2"  # 递归调用list_file函数,遍历子目录
		else
			echo "$2 file $f"  # 如果当前项是一个文件,则输出文件信息
		fi
	done
}

# 调用list_file函数,并传入第一个命令行参数作为要遍历的目录,同时传入一个空白的字符串作为初始的目录前缀
list_file $1 "├── "



40.数组遍历指定的目录

#!/bin/bash

# 接受一个目录作为参数,并将该目录下的所有文件存储在名为files的数组中
files=(`ls $1`)

# 循环遍历数组files中的所有元素
for((i=0;i<${#files[*]};i++)); do
        echo ${files[$i]}  # 输出数组中第i个元素(即文件名)
done


41.从标准输入读取 n 次字符串,每次输入的字符串保存在数组 array 中。

#!/bin/bash
# 设置循环次数
n=5
# 使用for循环遍历数组
for ((i=0; i<n; i++)); do
    # 提示用户输入字符串
    echo "Please input string... $((i + 1))"
    # 读取用户输入并存储到数组中
    read array[$i]
    # 将数组中的元素赋值给变量b
    b=${array[$i]}
    # 打印出变量b的值
    echo "$b"
done

42.将字符串中的字母逐个放入数组,并输出到标准输出

#!/bin/bash

# 定义字符串
str="hello"
# 获取字符串长度
len=${#str}

# 循环遍历字符串中的每个字符,并将其存入数组
for ((i=0; i<$len; i++))
do
    # 从字符串中提取第 i 个字符并存储在变量 char 中
    char="${str:i:1}"
    # 将字符存入数组中
    array[$i]=$char
# 输出数组中的每个元素到标准输出
    echo ${array[$i]}
done

43.把1~3这3个数字存到数组中,分别乘以8后再依次输出

#!/bin/bash
# 将数字 1 到 3 存入数组
array=(`seq 3`)
# 循环遍历数组中的每个数字,并乘以 8 后依次输出
for ((i=0; i<${#array[*]}; i++))
do
    # 计算乘以 8 后的结果
    result=$((array[$i] * 8))
    # 输出结果
    echo $result
done

44.输出如下内容中字母数不大于6的单词。

cat is favorite to eat fish

#!/bin/bash

# 定义一个包含多个单词的数组
array=(cat is favorite to eat fish)

# 使用for循环遍历数组中的每个元素
for ((i=0;i<${#array[*]};i++))
do
        # 使用expr命令获取当前元素的长度,并与6进行比较
        if [ `expr length ${array[$i]}` -le 6 ]; then
                echo ${array[$i]}  # 如果长度小于等于6,输出当前元素
        fi
done

45.写一个bash脚本以统计一个文本文件nowcoder.txt 中每个单词出现的个数。

为了简单起
见,你可以假设:wordcount.txt只包括小写字母和空格,每个单词只由小写字母组成,单词间由一个或
多个空格字符分隔。
假设 wordcount.txt 内容如下:
welcome nowcoder
welcome to nowcoder
nowcoder
你的脚本应当输出(以词频升序排列):
to 1 
welcome 2 
nowcoder 3 
说明:不要担心个数相同的单词的排序问题,每个单词出现的个数都是唯一的。
 

cat wordcount.txt |       # 从文件中读取内容并输出到标准输出(屏幕)
tr -s ' ' '\n' |          # 将空格替换为换行符,实现将文本中的单词分隔开来
sort |                    # 对单词进行排序,以便后续uniq命令进行统计
uniq -c |                 # 统计重复的单词,并输出重复次数和单词本身
sort -r |                 # 对统计结果进行逆序排序,以便出现次数最多的单词在前面
awk '{print $2" "$1}'    # 使用awk将单词和出现次数调换位置,并输出结果

46.监控cpu使用率的脚本

#利用while死循环+sleep实现
 #!/bin/bash
# 无限循环,持续监测 CPU 使用率
while : 
do
        # 使用 top 命令获取 CPU 使用率,然后用 grep 过滤出包含 '%Cpu(s)' 的行,
        # 再用 awk 提取出第 8 列(即 idle)的值,最后用 cut 命令按 '.' 分割并取第一个字段,
        # 这样我们得到了 CPU 空闲百分比的整数部分
        idle=$(top -bn1 | grep '%Cpu(s)' | awk '{print $8}' | cut -d. -f1)
        
        # 计算 CPU 使用率,假设 CPU 使用率等于 100 减去 CPU 空闲百分比
        use=$((100 - idle))
        
        # 如果 CPU 使用率大于 5%,则打印警告信息
        if [ $use -gt 5 ]; then
                echo "CPU use too high"
        fi
        
        # 等待 10 秒钟后再次检查 CPU 使用率
        sleep 10
done

  • 27
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值