Ubuntu22.04 编写一个带向导的sh脚本
采用逐次修改,最终完成代码的形式,以方便理解如何完成一段sh代码的编写。
1、确定需求:
1.1脚本1'fosh_install.sh'托管于GitHub,通过curl下载地址获得并直接运行
1.2运行'fosh_install.sh'时,通过检测/opt/FormID/sh/fosh.sh是否存在,若无则提示并创建目录,将这个目录加入$path变量,然后下载脚本2'fosh.sh'存至指定目录'/opt/FormID/sh'下,下载latest.version到'/opt/FormID/sh/fosh.version'提示用户退出后运行bash fosh.sh进入脚本,10s倒计时后退出。若/opt/FormID/sh/fosh.sh存在,下载GitHub上的latest.ver,读取latest_version存入$lv,读取/opt/FormID/sh/fosh.version中的$uv,比较,若有新版本,提示最新版本号以及询问是否更新脚本的版本,更新后变更$uv.
1.3用户运行'fosh.sh'时,若网络不通则提示,否则查询/opt/FormID/sh/fosh.version中的$if_updtae,值为yes则查询更新。然后列出功能清单,等待用户输入选择。
1.4主menu包含'1.安装常用工具'/'2.信息查询'/'3.设置是否更新FormID脚本'/'0.退出脚本';menu1包含'1.1 安装curl/net-tools等软件安装'/'1.2 docker 安装'/'1.3 Node.js v20安装'/'1.4 Python3.9安装'/'1.5 最新版pip安装'/'返回上一层';menu2 包含'2.1 实时系统进程查看htop'/'2.2 查看磁盘空间信息'/'2.3 查询Node.js版本'/'0 返回上一层'。
2、分析需求整理架构及运行逻辑
整理程序架构,定义功能functions,再把function填入架构当中(都说这是功能模块化),最后再美化美化。(先制作本地文件,涉及文件fosh_install.sh/fosh.sh/latest.version,完成后上传至GitHub。)ok,Go!Go!Go!
3、脚本架构
fosh.sh执行逻辑:
#!/bin/bash
# 定义函数1-判断与GitHub的网络连接是否通畅
check_github_connection() {
echo "执行检查与GitHub的网络连接功能"
# 在这里添加检查GitHub连接的具体逻辑
}
# 定义menu1_list
menu1_list() {
# 提示用户进一步选择
read -p "请选择以下选项:
1. 子功能1
2. 子功能2
3. 子功能3
0. 返回上一层
请输入数字(1-3,0): " menu1_sub_choice
# 根据用户输入的数字调用相应的子函数或返回上一层
case $menu1_sub_choice in
1)
echo "执行menu1子功能1"
;;
2)
echo "执行menu1子功能2"
;;
3)
echo "执行menu1子功能3"
;;
0)
echo "返回上一层。"
;;
*)
echo "无效的输入,输入必须为1、2、3或0。"
;;
esac
}
# 定义menu2_list
menu2_list() {
# 提示用户进一步选择
read -p "请选择以下选项:
1. 子功能1
2. 子功能2
3. 子功能3
0. 返回上一层
请输入数字(1-3,0): " menu2_sub_choice
# 根据用户输入的数字调用相应的子函数或返回上一层
case $menu2_sub_choice in
1)
echo "执行menu2子功能1"
;;
2)
echo "执行menu2子功能2"
;;
3)
echo "执行menu2子功能3"
;;
0)
echo "返回上一层。"
;;
*)
echo "无效的输入,输入必须为1、2、3或0。"
;;
esac
}
# 定义menu3函数
menu3() {
echo "执行menu3函数"
# 在这里添加menu3函数的具体逻辑
}
# 定义sh_exit函数
sh_exit() {
echo "退出脚本"
exit 0
}
# 定义打印主菜单的函数
print_main_menu() {
echo "
1. 安装常用工具
2. 信息查询
3. 设置是否自动检查更新FormID脚本
0. 退出脚本"
}
# 主循环
while true; do
print_main_menu
# 提示用户输入1-4的数字
read -p "请输入数字(0-3): " main_menu
# 根据用户输入的数字调用相应的函数或退出脚本
case $main_menu in
1)
check_github_connection
;;
2)
# 执行信息查询
;;
3)
# 执行设置是否自动检查更新FormID脚本
;;
0)
sh_exit
;;
*)
echo "无效的输入,输入必须为1、2、3或0。"
;;
esac
done
4、处理各个涉及到的函数并添到相应的执行位置
4.1与GitHub之间的网络连接测测试Function
#定义检查本地与GitHub站点的连接状态
check_github_connection() {
net_status="Failed"
if curl --output /dev/null --silent --head --fail "https://www.github.com"; then
net_status="OK"
echo "你与GitHub站点的网络连接是 $net_status 的。"
else
net_status="Failed"
echo "$net_status, 与GitHub的网络连接失败。"
fi
}
# 执行检测
check_github_connection
4.2安装curl wget net-tools等常用软件
#定义安装curl wget net-tools等常用软件的Function
install_common_tools(){
apt-get update
clear
apt-get install -y curl wget net-tools ca-certificates gnupg htop nano screen git vim iproute2
clear
}
#执行Function
install_common_tools
4.3 10s后退出脚本的函数
#定义10s延时的的函数
delay_10s(){
for i in {10..1}; do
echo -ne "等待 $i 秒后返回...\r"
sleep 1
done
}
4.4Docker 安装的Function
#定义Docker安装的Function
install_docker(){
#删除之前安装的docker相关软件
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
# 更新软件库数据源
apt-get update
#安装可能会使用上的软件
apt-get install ca-certificates curl gnupg
#安装gpg准备文件。
sudo install -m 0755 -d /etc/apt/keyrings
#下载gpg文件到指定目录
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
#变更gpg文件权限
sudo chmod a+r /etc/apt/keyrings/docker.gpg
#添加资源库到镜像源配置文件中
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
#更新软件库镜像源
sudo apt-get update
#安装docker docker-compose等
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin
docker-compose docker-compose-plugin
#查看docker版本及docker-compose版本,以确定安装及运行情况,有无错返回数据即可。
clear
docker -v
docker-compose -v
echo "显示版本号即表示安装成功~~~"
delay_10s
}
#执行Function
install_docker
4.5安装Node.js v20
#定义安装Node.js v20的函数
install_nodejs20(){
#更新镜像源
sudo apt-get update
#安装必要的软件
sudo apt-get install -y ca-certificates curl gnupg
#创建gpg.key的存放目录
sudo mkdir -p /etc/apt/keyrings
#下载gpg.key并安装到指定目录
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
#设定版本变量
NODE_MAJOR=20
#获取并添加对应版本的的软件库源
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
#重新更新镜像源
sudo apt-get update
#安装nodejs
sudo apt-get install nodejs -y
clear
#查看node.js版本
nodejs -v
echo "显示版本号即表示安装成功~~~"
delay_10s
}
#执行Function
install_nodejs20
4.6安装Python3.9
#定义安装Python3.9的函数
install_python39(){
#更新镜像源
apt-get update
#安装software-properties-common
apt-get install software-properties-common
#添加python3的镜像源库、key,并更新一次镜像源
add-apt-repository ppa:deadsnakes/ppa
#安装python3.9
apt-get install python3.9 -y
clear
#查看python3版本
python3 -V
echo "显示版本号即表示安装成功~~~"
delay_10s
}
#执行Function
install_python39
4.7安装最新版pip
#定义安装最新版pip的函数
install_pip(){
#更新镜像源
apt-get update
#安装pip3
apt-get install python3-pip -y
#默认值可能是22.几,升级到最新
pip install pip -U
clear
#查看pip版本
pip -V
echo "显示版本号即表示安装成功~~~"
delay_10s
}
#执行Function
install_pip
5、把函数都放进结构中,调试一下,修正了之前的函数里面的错误。
#生成fosh.sh的功能脚本
#!/bin/bash
#定义检查本地与GitHub站点的连接状态
check_github_connection() {
net_status="Failed"
if curl --output /dev/null --silent --head --fail "https://www.github.com"; then
net_status="OK"
echo "你与GitHub站点的网络连接是 $net_status 的。"
else
net_status="Failed"
echo "$net_status, 与GitHub的网络连接失败。"
fi
}
#定义安装curl wget net-tools等常用软件的Function
install_common_tools(){
apt-get update
clear
apt-get install -y curl wget net-tools ca-certificates gnupg htop nano screen git vim iproute2
echo "常用软件已安装完成。"
delay_10s
clear
}
#定义10s延时的的函数
delay_10s(){
for i in {10..1}; do
echo -ne "等待 $i 秒后返回...\r"
sleep 1
done
}
#定义Docker安装的Function
install_docker(){
#删除之前安装的docker相关软件
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove -y $pkg; done
# 更新软件库数据源
apt-get update
#安装可能会使用上的软件
apt-get install -y ca-certificates curl gnupg
#安装gpg准备文件。
sudo install -m 0755 -d /etc/apt/keyrings
#下载gpg文件到指定目录
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
#变更gpg文件权限
sudo chmod a+r /etc/apt/keyrings/docker.gpg
#添加资源库到镜像源配置文件中
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
#更新软件库镜像源
sudo apt-get update
#安装docker docker-compose等
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose docker-compose-plugin
#查看docker版本及docker-compose版本,以确定安装及运行情况,有无错返回数据即可。
docker -v
docker-compose -v
echo "显示版本号即表示安装成功~~~"
delay_10s
clear
}
#定义安装Node.js v20的函数
install_nodejsv20(){
#更新镜像源
sudo apt-get update
#安装必要的软件
sudo apt-get install -y ca-certificates curl gnupg
#创建gpg.key的存放目录
sudo mkdir -p /etc/apt/keyrings
#下载gpg.key并安装到指定目录
sudo curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
#设定版本变量
NODE_MAJOR=20
#获取并添加对应版本的的软件库源
sudo echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
#重新更新镜像源
sudo apt-get update
#安装nodejs
sudo apt-get install -y nodejs
#查看node.js版本
nodejs -v
echo "显示版本号即表示安装成功~~~"
delay_10s
clear
}
#定义检查nodejs未安装或低于v20则安装node.js v20的函数
check_node_version(){
node_version=$(node -v 2>/dev/null) # 获取 Node.js 版本,忽略错误信息
if [ -n "$node_version" ]; then
echo "已安装 Node.js,版本:$node_version"
# 提取主版本号
major_version=$(echo "$node_version" | cut -d. -f1)
if [ "$major_version" -ge 20 ]; then
echo "目前Node.js 版本为:$node_version,无需安装!"
sleep 5
exit 0
else
echo "Node.js 版本 < 20,即刻安装Node.js v20"
sleep 5
install_nodejsv20 # 如果版本小于 20,运行安装函数
fi
else
echo "未安装 Node.js,即刻安装Node.js v20"
sleep 5
install_nodejsv20 # 如果未安装 Node.js,运行安装函数
fi
}
#定义安装Python3.9的函数
install_python39(){
clear
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
NC="\033[0m"
# 系统检测
OS=$(cat /etc/os-release | grep -o -E "Debian|Ubuntu|CentOS" | head -n 1)
if [[ $OS == "Debian" || $OS == "Ubuntu" || $OS == "CentOS" ]]; then
echo -e "检测到你的系统是 ${YELLOW}${OS}${NC}"
else
echo -e "${RED}很抱歉,你的系统不受支持!${NC}"
exit 1
fi
# 检测安装Python3的版本
VERSION=$(python3 -V 2>&1 | awk '{print $2}')
# 获取最新Python3版本
PY_VERSION=$(curl -s https://www.python.org/ | grep "downloads/release" | grep -o 'Python [0-9.]*' | grep -o '[0-9.]*')
# 卸载Python3旧版本
if [[ $VERSION == "3"* ]]; then
echo -e "${YELLOW}你的Python3版本是${NC}${RED}${VERSION}${NC},${YELLOW}最新版本是${NC}${RED}${PY_VERSION}${NC}"
read -p "是否确认升级最新版Python3?默认不升级 [y/N]: " CONFIRM
if [[ $CONFIRM == "y" ]]; then
if [[ $OS == "CentOS" ]]; then
echo ""
rm-rf /usr/local/python3* >/dev/null 2>&1
else
apt --purge remove python3 python3-pip -y
rm-rf /usr/local/python3*
fi
else
echo -e "${YELLOW}已取消升级Python3${NC}"
exit 1
fi
else
echo -e "${RED}检测到没有安装Python3。${NC}"
read -p "是否确认安装最新版Python3?默认安装 [Y/n]: " CONFIRM
if [[ $CONFIRM != "n" ]]; then
echo -e "${GREEN}开始安装最新版Python3...${NC}"
else
echo -e "${YELLOW}已取消安装Python3${NC}"
exit 1
fi
fi
echo "卸载机器上的py完成。"
sleep 5
# 安装相关依赖
if [[ $OS == "CentOS" ]]; then
yum update
yum groupinstall -y "development tools"
yum install wget openssl-devel bzip2-devel libffi-devel zlib-devel -y
else
apt update
apt install wget build-essential libreadline-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev -y
fi
# 安装python3
cd /root/
echo "此处指定版本号为3.9.0"
sleep 5
PY_VERSION=3.9.0
wget https://www.python.org/ftp/python/${PY_VERSION}/Python-"$PY_VERSION".tgz
echo "刚刚是获取压缩包"
sleep 5
tar -zxf Python-${PY_VERSION}.tgz
cd Python-${PY_VERSION}
./configure --prefix=/usr/local/python3
make -j $(nproc)
make install
if [ $? -eq 0 ];then
rm -f /usr/local/bin/python3*
rm -f /usr/local/bin/pip3*
ln -sf /usr/local/python3/bin/python3 /usr/bin/python3
ln -sf /usr/local/python3/bin/pip3 /usr/bin/pip3
clear
echo -e "${YELLOW}Python3安装${GREEN}成功,${NC}版本为: ${NC}${GREEN}${PY_VERSION}${NC}"
else
clear
echo -e "${RED}Python3安装失败!${NC}"
exit 1
fi
cd /root/ && rm -rf Python-${PY_VERSION}.tgz && rm -rf Python-${PY_VERSION}
#更新镜像源
#apt-get update
#安装software-properties-common
#apt-get install -y software-properties-common
#添加python3的镜像源库、key,并更新一次镜像源
#add-apt-repository ppa:deadsnakes/ppa
#安装python3.9
#apt-get install-y python3.9
#clear
#查看python3版本
python3 -V
echo "显示版本号即表示安装成功~~~"
delay_10s
}
#定义安装最新版pip的函数
install_pip(){
#更新镜像源
apt-get update
#安装pip3
apt-get install python3-pip -y
#默认值可能是22.几,升级到最新
pip install pip -U
clear
#查看pip版本
pip -V
echo "显示版本号即表示安装成功~~~"
delay_10s
}
#主程序函数定义开始~~~~
# 定义menu1_list
menu1_list() {
# 提示用户进一步选择
read -p "请选择以下选项:
1. 安装curl wget net-tools等常用软件
2. Docker 安装
3. 安装Node.js v20
4. 安装Python3.9
0. 返回上一层
请输入数字(1-4,0): " menu1_sub_choice
# 根据用户输入的数字调用相应的子函数或返回上一层
case $menu1_sub_choice in
1)
install_common_tools
;;
2)
install_docker
;;
3)
check_node_version
;;
4)
install_python39
;;
0)
echo "返回上一层。"
;;
*)
echo "无效的输入,输入必须为1、2、3、4或0。"
;;
esac
}
# 定义menu2_list
menu2_list() {
# 提示用户进一步选择
read -p "请选择以下选项:
1. 实时系统进程查看
2. 查看磁盘空间信息
3. 查询Node.js版本
0. 返回上一层
请输入数字(1-3,0): " menu2_sub_choice
# 根据用户输入的数字调用相应的子函数或返回上一层
case $menu2_sub_choice in
1)
htop
;;
2)
df -h
delay_10s
;;
3)
node_version=$(node -v 2>/dev/null) # 获取 Node.js 版本,忽略错误信息
if [ -n "$node_version" ]; then
echo "已安装 Node.js,版本:$node_version"
sleep 5
else
echo "本机未安装任何版本的 Node.js"
sleep 5
fi
;;
0)
echo "返回上一层。"
;;
*)
echo "无效的输入,输入必须为1、2、3或0。"
;;
esac
}
# 定义设置是否更新FormID脚本函数
check_update() {
#"询问是否设置检查"
read -p "请选择以下选项:
e. 开启每次启动检测并自动更新本脚本
d. 查看磁盘空间信息
0. 返回上一层
请输入数字(1-3,0): " check_update_sub_choice
# 根据用户输入的数字调用相应的子函数或返回上一层
case $check_update_sub_choice in
1)
echo "开启自动更新本脚本。"
sleep 5
;;
2)
echo "禁用自动更新本脚本。"
sleep 5
;;
0)
echo "返回上一层。"
;;
*)
echo "无效的输入,输入必须为e、d或0。"
;;
esac
}
# 定义sh_exit函数
sh_exit() {
echo "退出脚本"
exit 0
}
# 定义打印主菜单的函数
print_main_menu() {
echo "
1. 安装常用工具
2. 信息查询
3. 设置是否自动检查更新FormID脚本
0. 退出脚本"
}
# 主程序开始
clear
check_github_connection
sleep 3
while true; do
print_main_menu
# 提示用户输入1-4的数字
read -p "请输入数字(0-3): " main_menu
# 根据用户输入的数字调用相应的函数或退出脚本
case $main_menu in
1)
menu1_list
;;
2)
menu2_list
;;
3)
check_update
;;
0)
sh_exit
;;
*)
echo "无效的输入,输入必须为1、2、3或0。"
;;
esac
done