# 项目四 Shell数组与函数
[toc]
【实训任务】
本实训的主要任务是通过定义和操作数组实现对多个数据的集合的存储和处理,使用函数参数给函数传递数据并根据参数的值执行相应的操作,以及编写函数完成特定的任务等。
【实训目录】
(1)掌握索引数组的定义方法,使用数组编写Shell脚本。
(2)掌握关联数组的定义方法,使用数组编写Shell脚本。
(3)掌握函数的定义方法,编写Shell函数脚本。
(4)掌握函数参数的使用方法和变量作用域,编写Shell函数脚本。
【实训内容】
(1)编写Shell脚本,使用数组实现连接状态统计。
(2)编写Shell脚本,使用数组实现网站日志统计。
(3)编写Shell脚本,使用函数实现冒泡排序。
(4)编写Shell脚本,使用函数实现计数和快速排序。
【实训环境】
在进行本项目的实训操作前,提前准备好Linux操作系统环境,RHEL、CentOS Stream、Debian、Ubuntu、华为openEuler、麒麟openKylin等常见Linux发行版都可以进行项目实训。
## 项目实施
### 任务一 编写Shell数组脚本
#### 1.任务描述
(1)在Linux操作系统中创建Shell脚本array-count.sh,根据输入的操作系统和版本文件内容,统计不同操作系统出现的次数,输出每种操作系统的计数结果。
(2)在Linux操作系统中创建Shell脚本array-shelltype.sh,根据系统/etc/passwd文件中的用户信息,统计不同Shell类型的用户数量,输出每种Shell类型的用户数量。
(3)在Linux操作系统中创建Shell脚本array-stat.sh,统计系统中不同状态的网络连接,输出每种状态及其连接数量。
#### 2.任务实施
(1)在家目录中,创建脚本文件array-count.sh
[root@redhat01 ~]# vim osversion.txt
[root@redhat01 ~]# cat osversion.txt
Openeuler,linux
RHEL9,linux
Ubuntu22,linux
Debian,linux
Solaris,unix
IBM-AIX,unix
HP-UX,unix
[root@redhat01 ~]# vim array-count.sh
[root@redhat01 ~]# cat array-count.sh
#!/bin/bash
# 声明一个关联数组以存储操作系统统计数
declare -A os_count
# 逐行读取文件
while IFS=',' read -r name os
do
# 增加当前操作系数计数
((os_count[$os]++))
done < osversion.txt
# 输出操作系统计数
echo "Operate System Count:"
for os in "${!os_count[@]}"
do
echo "$os: ${os_count[$os]}"
done
[root@redhat01 ~]# bash array-count.sh
Operate System Count:
linux: 4
unix: 3
(2)在家目录中,创建脚本文件array-shelltype.sh。
```bash
[root@redhat01 ~]# vim array-shelltype.sh
[root@redhat01 ~]# cat array-shelltype.sh
#!/bin/bash
declare -A shells
while IFS=':' read -r user _ _ _ _ _ shell _; do
shells[$shell]=$((shells[$shell] + 1))
done < /etc/passwd
for shell in "${!shells[@]}"; do
echo "Shell $shell is used by ${shells[$shell]} users"
done
[root@redhat01 ~]# bash array-shelltype.sh
Shell /sbin/nologin is used by 27 users
Shell /bin/bash is used by 3 users
Shell /bin/sync is used by 1 users
Shell /usr/sbin/nologin is used by 5 users
Shell /sbin/halt is used by 1 users
Shell /sbin/shutdown is used by 1 users
```
(3)在家目录中,创建脚本文件array-stat.sh。
[root@redhat01 ~]# vim array-stat.sh
[root@redhat01 ~]# cat array-stat.sh
#!/bin/bash
declare -A connections
while read line; do
state=$(echo $line | awk '{print $2}')
if [ -z "${connections[$state]}" ]; then
connections[$state]=1
else
connections[$state]=$((connections[$state] + 1))
fi
done < <(ss -an | awk '{print $1,$2}')
for state in "${!connections[@]}"; do
echo "State $state: ${connections[$state]}"
done
[root@redhat01 ~]# bash array-stat.sh
State ESTAB: 443
State UNCONN: 103
State LISTEN: 50
State State: 1
### 任务二 编写Shell函数脚本
#### 1.任务描述
(1)在Linux操作系统中创建Shell脚本func-fibonacci.sh,通过定义函数和循环计算,实现生成斐波那契数列并将其输出的功能。
(2)在Linux操作系统中创建Shell脚本func-bubble-sort.sh,通过冒泡排序算法实现对数组的排序,通过函数和循环完成排序过程,最终输出原始数组和排序后的数组。
(3)在Linux操作系统中创建Shell脚本func-process-check.sh,获取并输出当前CPU使用率排名前5的进程信息。
#### 2.任务实施
(1)在用户家目录中,创建脚本文件func-fibonacci.sh。
[root@redhat01 ~]# vim func-fibonacci.sh
[root@redhat01 ~]# cat func-fibonacci.sh
#!/bin/bash
# 定义函数来生成斐波那契数列
generate_fibonacci() {
local n=$1
local fib_sequence=()
# 初始化前两个数
fib_sequence[0]=0
fib_sequence[1]=1
# 计算并存储数列中的下一个元素
for ((i=2; i<=n; i++))
do
fib_sequence[i]=$((fib_sequence[i-1] + fib_sequence[i-2]))
done
# 将数列作为返回值
echo "${fib_sequence[@]}"
}
# 调用函数生成斐波那契数列并输出
fibonacci_sequence=$(generate_fibonacci 20)
echo "Fibonacci Sequence:"
echo $fibonacci_sequence
[root@redhat01 ~]# bash func-fibonacci.sh
Fibonacci Sequence:
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
(2)在家目录中,创建脚本文件func-bubble-sort.sh。
```bash
[root@redhat01 ~]# vim func-bubble-sort.sh
[root@redhat01 ~]# cat func-bubble-sort.sh
#!/bin/bash
function bubble_sort {
local arr=("$@")
local n=${#arr[@]}
local temp
for((i=0; i<n-1; i++)); do
for((j=0; j<n-i-1; j++)); do
if [[ ${arr[j]} -gt ${arr[$((j+1))]} ]]; then
temp=${arr[j]}
arr[$j]=${arr[$((j+1))]}
arr[$((j+1))]=$temp
fi
done
done
echo ${arr[@]}
}
arr=(5 3 8 4 1)
sorted_arr=($(bubble_sort ${arr[@]}))
echo "Original array: ${arr[@]}"
echo "Sorted array: ${sorted_arr[@]}"
[root@redhat01 ~]# bash func-bubble-sort.sh
Original array: 5 3 8 4 1
Sorted array: 1 3 4 5 8
```
(3)在家目录中,创建脚本文件func-process-check.sh。
[root@redhat01 ~]# vim func-process-check.sh
[root@redhat01 ~]# cat func-process-check.sh
#!/bin/bash
# 定义函数,获取并输出CPU使用率排名前5的进程信息
get_top_processes() {
# 使用 top 命令获取进程信息
top_output=$(top -b -n 1 -o %CPU)
# 提取前5个进程信息
top_processes=$(echo "$top_output" | awk 'NR>7 {print $1, $9, $12}' | head -n 5)
# 输出前5个进程的PID、CPU使用率和进程正在执行的实际命令
echo "Top 5 processes by CPU usage:"
counter=0
while read -r pid cpu command; do
cpu=$(echo "$cpu" | awk '{printf "%.1f%%", $1}')
echo "PID: $pid, CPU Usage: $cpu, Command: $command"
((counter++))
if [[ $counter -eq 5 ]]; then
break
fi
done <<< "$top_processes"
}
# 调用函数
get_top_processes
[root@redhat01 ~]# bash func-process-check.sh
Top 5 processes by CPU usage:
PID: 10974, CPU Usage: 6.2%, Command: top
PID: 1, CPU Usage: 0.0%, Command: systemd
PID: 2, CPU Usage: 0.0%, Command: kthreadd
PID: 3, CPU Usage: 0.0%, Command: rcu_gp
PID: 4, CPU Usage: 0.0%, Command: rcu_par_gp