This commit is contained in:
107
File/Shell/Build_Core_Tar.sh
Normal file
107
File/Shell/Build_Core_Tar.sh
Normal file
@@ -0,0 +1,107 @@
|
||||
#!/bin/bash
|
||||
|
||||
#############################################################################################
|
||||
# 用途: 本脚本用于大包内核离线升级包
|
||||
# 作者: 丁辉
|
||||
# 编写时间: 2023-12-03
|
||||
# 更新时间: 2024-05-20
|
||||
#############################################################################################
|
||||
|
||||
# 加载检测脚本
|
||||
source <(curl -sS https://gitee.com/offends/Linux/raw/main/File/Shell/Check_command.sh)
|
||||
|
||||
# Centos内核文件: https://elrepo.org/linux/kernel/
|
||||
# Ubuntu内核文件: https://kernel.ubuntu.com/mainline/ 国内: https://mirrors.edge.kernel.org/pub/linux/kernel/
|
||||
|
||||
# 存放Cenots8内核RPM文件包数组
|
||||
Centos8_RPM=(
|
||||
"https://elrepo.org/linux/kernel/el8/x86_64/RPMS/kernel-lt-5.4.262-1.el8.elrepo.x86_64.rpm"
|
||||
"https://elrepo.org/linux/kernel/el8/x86_64/RPMS/kernel-lt-modules-5.4.262-1.el8.elrepo.x86_64.rpm"
|
||||
"https://elrepo.org/linux/kernel/el8/x86_64/RPMS/kernel-lt-core-5.4.262-1.el8.elrepo.x86_64.rpm"
|
||||
)
|
||||
|
||||
Centos7_RPM=(
|
||||
"https://elrepo.org/linux/kernel/el7/x86_64/RPMS/kernel-lt-5.4.262-1.el7.elrepo.x86_64.rpm"
|
||||
)
|
||||
|
||||
function CURL_UBUNTU_DEB(){
|
||||
CHECK_CPU
|
||||
SEND_INFO "正在下载内核DEB文件包,请稍后"
|
||||
VERSION=$(curl -s https://kernel.ubuntu.com/mainline/ | awk -F 'href="' '{print $2}' | awk -F '/"' '{print $1}' | sort -V | grep -v rc | grep -v Name | tail -n 1)
|
||||
FILES=$(curl -s https://kernel.ubuntu.com/mainline/v6.6.4/amd64/ | grep deb | awk -F 'href="' '{print $2}' | awk -F '.deb' '{print $1".deb"}' | grep -v linux-headers)
|
||||
URL="https://kernel.ubuntu.com/mainline/$VERSION/$ARCH_TYPE_2"
|
||||
for i in ${FILES[@]}
|
||||
do
|
||||
curl -sO $URL/$i
|
||||
done
|
||||
VERSION="Ubuntu"
|
||||
SEND_INFO "开始打包: $VERSION 离线内核升级包"
|
||||
CHECK_COMMAND_ECHO rm -rf linux-headers-*
|
||||
curl -sO https://gitee.com/offends/Linux/raw/main/File/Shell/Check_command.sh
|
||||
sed -i.bak 's/source <(curl -sS https:\/\/gitee.com\/offends\/Linux\/raw\/main\/File\/Shell\/Check_command.sh)/source .\/Check_command.sh/g' Core.sh
|
||||
CHECK_COMMAND_ECHO tar -zcvf $VERSION\_Core.tar.gz *.deb Check_command.sh Core.sh
|
||||
SEND_INFO "正在清理临时文件"
|
||||
CHECK_COMMAND_ECHO rm -rf *.deb && mv Core.sh.bak Core.sh
|
||||
}
|
||||
|
||||
function CHECK_CENTOS_FILE(){
|
||||
SEND_INFO "开始打包: $VERSION 离线内核升级包"
|
||||
curl -sO https://gitee.com/offends/Linux/raw/main/File/Shell/Check_command.sh
|
||||
sed -i.bak 's/source <(curl -sS https:\/\/gitee.com\/offends\/Linux\/raw\/main\/File\/Shell\/Check_command.sh)/source .\/Check_command.sh/g' Core.sh
|
||||
CHECK_COMMAND_ECHO tar -zcvf $VERSION\_Core.tar.gz *.rpm Check_command.sh Core.sh
|
||||
SEND_INFO "正在清理临时文件"
|
||||
CHECK_COMMAND_ECHO rm -rf *.rpm && mv Core.sh.bak Core.sh
|
||||
}
|
||||
|
||||
# 判断用户传入的参数为哪个系统
|
||||
function CHECK_USER_READ(){
|
||||
case $1 in
|
||||
Centos7)
|
||||
SEND_INFO "正在下载内核RPM文件包,请稍后"
|
||||
for i in ${Centos7_RPM[@]}
|
||||
do
|
||||
curl -sO $i
|
||||
VERSION="CentOS7"
|
||||
done
|
||||
CHECK_CENTOS_FILE
|
||||
;;
|
||||
Centos8)
|
||||
SEND_INFO "正在下载内核RPM文件包,请稍后"
|
||||
for i in ${Centos8_RPM[@]}
|
||||
do
|
||||
curl -sO $i
|
||||
VERSION="CentOS8"
|
||||
done
|
||||
CHECK_CENTOS_FILE
|
||||
;;
|
||||
Ubuntu)
|
||||
CURL_UBUNTU_DEB
|
||||
;;
|
||||
--help | -h)
|
||||
echo "Usage: script_name [OPTIONS] [ARGUMENTS]"
|
||||
echo ""
|
||||
echo "Description:"
|
||||
echo " Offends"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -h, --help 显示此帮助信息"
|
||||
echo " Centos7 打包Centos7内核离线包"
|
||||
echo " Centos8 打包Centos8内核离线包"
|
||||
echo " Ubuntu 打包Centos8内核离线包"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " 示例 1: ./Build_Core_Tar.sh Centos7"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
SEND_ERROR "参数错误,请使用 --help,-h 查看支持版本"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
function ALL(){
|
||||
CHECK_NETWORK
|
||||
CHECK_USER_READ $@
|
||||
}
|
||||
|
||||
ALL $@
|
284
File/Shell/Check_command.sh
Normal file
284
File/Shell/Check_command.sh
Normal file
@@ -0,0 +1,284 @@
|
||||
#!/bin/bash
|
||||
|
||||
#############################################################################################
|
||||
# 用途: 提供一些常用的函数,拱其他脚本调用
|
||||
# 作者: 丁辉
|
||||
# 编写时间: 2023-11-27
|
||||
#############################################################################################
|
||||
|
||||
# 加载检测脚本
|
||||
# source <(curl -sS https://gitee.com/offends/Shell/raw/main/Check_command.sh)
|
||||
|
||||
# 定义颜色
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
GREEN='\033[32m'
|
||||
YELLOW='\033[33m'
|
||||
|
||||
# 定义时间格式
|
||||
TIME="+%Y-%m-%d %H:%M:%S"
|
||||
|
||||
# 定义函数 send_info
|
||||
function SEND_INFO() {
|
||||
info=$1
|
||||
echo -e "${GREEN}$(date "$TIME") INFO: $info${NC}"
|
||||
}
|
||||
|
||||
# 定义函数 send_warn
|
||||
function SEND_WARN() {
|
||||
warn=$1
|
||||
echo -e "${YELLOW}$(date "$TIME") WARN: $warn${NC}"
|
||||
}
|
||||
|
||||
# 定义函数 send_error
|
||||
function SEND_ERROR() {
|
||||
error=$1
|
||||
echo -e "${RED}$(date "$TIME") ERROR: $error${NC}"
|
||||
}
|
||||
|
||||
# print输出绿色字体
|
||||
function GREEN_PRINTF() {
|
||||
info=$1
|
||||
printf "${GREEN}$(date "$TIME") INFO: $info${NC}\n"
|
||||
}
|
||||
|
||||
# 打印系统信息
|
||||
function FUNC_PRINT_SYSTEM_INFO() {
|
||||
# 获取系统信息
|
||||
CENTOS_VERSION=$(cat /etc/os-release | grep PRETTY_NAME= | awk -F '"' '{print $2}')
|
||||
KERNEL_VERSION=$(uname -a | awk '{print $3}')
|
||||
CPU_MODEl=$(cat /proc/cpuinfo | grep 'model name' | head -1 | awk -F ':' '{print $2}' | sed 's#^[ \t]*##g')
|
||||
CPU_CORE=$(grep -c "processor" /proc/cpuinfo)
|
||||
MEMORY_SIZE=$(free -h | awk '/Mem/ {print $2}')
|
||||
|
||||
# 打印系统信息
|
||||
SEND_INFO "欢迎使用阿辉的脚本"
|
||||
SEND_INFO "当前系统信息如下: "
|
||||
SEND_INFO "=========================================================="
|
||||
SEND_INFO "服务器架构: $(arch)"
|
||||
SEND_INFO "系统版本: ${CENTOS_VERSION}"
|
||||
SEND_INFO "内核版本: ${KERNEL_VERSION}"
|
||||
SEND_INFO "内存大小: ${MEMORY_SIZE}"
|
||||
SEND_INFO "处理器核数: ${CPU_CORE}"
|
||||
SEND_INFO "处理器型号: ${CPU_MODEl}"
|
||||
SEND_INFO "=========================================================="
|
||||
}
|
||||
|
||||
# 检查服务器系统版本
|
||||
function CHECK_OS() {
|
||||
FWQ_NAME=$(cat /etc/os-release | grep '^NAME' | awk -F '"' '{print $2}')
|
||||
if [[ $FWQ_NAME == "CentOS Linux" ]] || [[ $FWQ_NAME == "CentOS Stream" ]];then
|
||||
OS=centos
|
||||
OS_VERSION=$(cat /etc/os-release | grep -oP 'VERSION_ID="\K[^"]+' | cut -d '.' -f 1)
|
||||
elif [[ $FWQ_NAME == "Debian GNU/Linux" ]];then
|
||||
OS=debian
|
||||
OS_VERSION=$(cat /etc/issue | awk -F ' ' '{print $3}')
|
||||
elif [[ $FWQ_NAME == "Ubuntu" ]];then
|
||||
OS=ubuntu
|
||||
OS_VERSION=$(cat /etc/os-release | grep VERSION_ID= | grep -oE '[0-9]+\.[0-9]+' | cut -d'.' -f1)
|
||||
else
|
||||
SEND_ERROR "无法识别的系统版本"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 判断服务器架构
|
||||
function CHECK_CPU() {
|
||||
if [ $(arch) = "x86_64" ] || [ $(arch) = "amd64" ]; then
|
||||
ARCH_TYPE_1=x86_64
|
||||
ARCH_TYPE_2=amd64
|
||||
elif [ $(arch) = "aarch64" ] || [ $(arch) = "arm64" ]; then
|
||||
ARCH_TYPE_1=aarch64
|
||||
ARCH_TYPE_2=arm64
|
||||
elif [ $(arch) = "i386" ]; then
|
||||
ARCH_TYPE=x86_64
|
||||
ARCH_TYPE_2=amd64
|
||||
else
|
||||
SEND_ERROR "无法识别的系统架构: $(arch)"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 启动内核更新脚本
|
||||
function CHECK_CORE(){
|
||||
# 询问是否需要升级内核
|
||||
read -p "是否需要升级内核 [Y/n]" is_core
|
||||
case $is_core in
|
||||
[yY][eE][sS]|[yY])
|
||||
curl -sLO https://gitee.com/offends/Offends/raw/main/Shell/Core.sh
|
||||
chmod +x Core.sh
|
||||
./Core.sh $@
|
||||
;;
|
||||
[nN][oO]|[nN])
|
||||
SEND_INFO "跳过内核更新"
|
||||
;;
|
||||
"")
|
||||
SEND_ERROR "值不能为空,请重新输入"
|
||||
;;
|
||||
*)
|
||||
SEND_ERROR "输入错误,请重新输入"
|
||||
CHECK_CORE
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 检查服务器网络连接
|
||||
function CHECK_NETWORK() {
|
||||
SEND_INFO "正在检查网络连接"
|
||||
PING=$(ping -c 3 www.baidu.com | grep 'icmp_seq' | wc -l)
|
||||
if [[ ${PING} -eq 0 ]];then
|
||||
SEND_ERROR "网络连接失败,请检查网络连接"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 检测文件是否存在
|
||||
function CHECK_FILE(){
|
||||
if [ ! -f "$@" ]; then
|
||||
SEND_ERROR "$@ 文件不存在"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 检测文件是否存在(多文件情况)
|
||||
function CHECK_FILES(){
|
||||
shopt -s nullglob
|
||||
for file in "$@"; do
|
||||
if [ ! -f "$file" ]; then
|
||||
SEND_ERROR "$file 文件不存在"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# 检测目录是否存在,不存在则创建
|
||||
function CHECK_DIR(){
|
||||
if [ ! -d "$@" ]; then
|
||||
mkdir -p "$@" > /dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
# 检测固定位置的二进制文件是否存在
|
||||
function CHECK_BIN(){
|
||||
if [ ! -f "$@" ]; then
|
||||
INSTALL_BIN=false
|
||||
fi
|
||||
}
|
||||
|
||||
# 检测命令是否执行正确,正确则输出$1,错误则输出$2并退出脚本
|
||||
function CHECK_COMMAND_TRUE() {
|
||||
if [ $? -eq 0 ]; then
|
||||
SEND_INFO "$1"
|
||||
else
|
||||
SEND_ERROR "$2"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 判断用户是否存在,不存在则创建
|
||||
function CHECK_USER(){
|
||||
if ! id -u "$@" >/dev/null 2>&1; then
|
||||
useradd -m -s /bin/bash --no-user-group "$@" > /dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
# 判断用户组是否存在,不存在则创建
|
||||
function CHECK_GROUP(){
|
||||
if ! grep -q "$@" /etc/group; then
|
||||
groupadd "$@" > /dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
# 用户加入组
|
||||
function ADD_USER_GROUP(){
|
||||
CHECK_USER "$1"
|
||||
CHECK_GROUP "$2"
|
||||
if ! id -nG "$1" | grep -qw "$2"; then
|
||||
SEND_INFO "正在将用户 $1 加入用户组 $2"
|
||||
usermod -aG "$2" "$1" > /dev/null 2>&1 || true
|
||||
fi
|
||||
id "$1" || true
|
||||
}
|
||||
|
||||
# 定义输出为空,并且失败不会退出脚本
|
||||
function NULL_TRUE(){
|
||||
eval "$*" > /dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
# 失败不会退出脚本,输出命令执行结果
|
||||
function NULL_TRUE_ECHO(){
|
||||
eval "$*" || true
|
||||
}
|
||||
|
||||
# 检测命令是否执行成功,不输出命令执行结果
|
||||
function CHECK_COMMAND_NULL() {
|
||||
# 执行传入的命令
|
||||
eval "$*" > /dev/null 2>&1
|
||||
# 检查命令执行状态
|
||||
if [ $? -ne 0 ]; then
|
||||
SEND_ERROR "执行失败, 退出脚本, 请检查命令是否正确: $*"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 检测命令是否执行成功,输出命令执行结果
|
||||
function CHECK_COMMAND_ECHO() {
|
||||
# 执行传入的命令
|
||||
eval "$*"
|
||||
# 检查命令执行状态
|
||||
if [ $? -ne 0 ]; then
|
||||
SEND_ERROR "执行失败, 退出脚本, 请检查命令是否正确: $*"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 网络安装软件
|
||||
function CHECK_INSTALL() {
|
||||
# 接收传递给脚本的参数列表
|
||||
packages=("$@")
|
||||
|
||||
log_file="/tmp/check_install_log" # 定义日志文件路径
|
||||
|
||||
for pkg in "${packages[@]}"; do
|
||||
if command -v yum >/dev/null 2>&1; then
|
||||
SEND_INFO "正在安装 $pkg,请稍后"
|
||||
yum install -y "$pkg" >>"$log_file" 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
SEND_ERROR "安装 $pkg 失败,请查看日志"
|
||||
tail -n 10 "$log_file" # 输出最后10行日志
|
||||
rm -rf $log_file
|
||||
exit 1
|
||||
fi
|
||||
elif command -v apt >/dev/null 2>&1; then
|
||||
SEND_INFO "正在安装 $pkg,请稍后"
|
||||
apt-get install -y "$pkg" >>"$log_file" 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
SEND_ERROR "安装 $pkg 失败,请查看日志"
|
||||
tail -n 10 "$log_file" # 输出最后10行日志
|
||||
rm -rf $log_file
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
SEND_ERROR "无法识别的系统软件包管理工具"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# 检测某个systemd服务是否存在
|
||||
function CHECK_SYSTEMD(){
|
||||
if ! command -v $@ >/dev/null 2>&1; then
|
||||
SEND_ERROR "错误,请检查 $@ 是否安装"
|
||||
exit 1
|
||||
else
|
||||
SEND_INFO "$@ 服务已安装"
|
||||
if ! systemctl status $@ >/dev/null 2>&1; then
|
||||
SEND_WARN "$@ 服务未启动,正在启动 $@ 服务"
|
||||
if ! systemctl start $@ >/dev/null 2>&1; then
|
||||
SEND_ERROR "$@ 服务启动失败,请检查 $@ 服务"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
27
File/Shell/Clean_git.sh
Normal file
27
File/Shell/Clean_git.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
#############################################################################################
|
||||
# 用途: 清理 Git 提交记录
|
||||
# 作者: 丁辉
|
||||
# 编写时间: 2024-01-03
|
||||
# 使用方法
|
||||
# curl -sfL https://gitee.com/offends/Linux/raw/main/File/Shell/Clean_git.sh | bash
|
||||
#############################################################################################
|
||||
|
||||
# 定义变量
|
||||
|
||||
# 你的分支名称
|
||||
BRANCH="main"
|
||||
|
||||
# 创建了一个新的分支
|
||||
git checkout --orphan latest_branch
|
||||
# 添加所有文件
|
||||
git add -A
|
||||
# 提交更改
|
||||
git commit -am "synchronization"
|
||||
# 删除分支
|
||||
git branch -D $BRANCH
|
||||
# 将当前分支重命名
|
||||
git branch -m $BRANCH
|
||||
# 最后,强制更新存储库
|
||||
git push -f origin $BRANCH
|
381
File/Shell/Core.sh
Normal file
381
File/Shell/Core.sh
Normal file
@@ -0,0 +1,381 @@
|
||||
#!/bin/bash
|
||||
|
||||
#############################################################################################
|
||||
# 用途: 内核版本升级
|
||||
# 作者: 丁辉
|
||||
# 编写时间: 2023-12-02
|
||||
# 本脚本支持: Centos7/Centos8/Debian10/Debian11/Debian12/Ubuntu* 内核升级
|
||||
#############################################################################################
|
||||
|
||||
# 检查服务器网络连接
|
||||
function CHECK_NETWORK() {
|
||||
PING=$(ping -c 3 www.baidu.com | grep 'icmp_seq' | wc -l)
|
||||
if [[ ${PING} -eq 0 ]];then
|
||||
SEND_ERROR "未检测到网络,跳过网络安装系统基础依赖"
|
||||
else
|
||||
CHECK_INSTALL curl
|
||||
fi
|
||||
}
|
||||
|
||||
function CHECK_INSTALL() {
|
||||
# 接收传递给脚本的参数列表
|
||||
packages=("$@")
|
||||
|
||||
log_file="/tmp/check_install_log" # 定义日志文件路径
|
||||
|
||||
for pkg in "${packages[@]}"; do
|
||||
if command -v yum >/dev/null 2>&1; then
|
||||
echo -e "\033[32m正在安装 $pkg,请稍后\033[0m"
|
||||
yum install -y "$pkg" >>"$log_file" 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "\033[31m安装 $pkg 失败,请查看日志\033[0m"
|
||||
tail -n 10 "$log_file" # 输出最后10行日志
|
||||
rm -rf $log_file
|
||||
exit 1
|
||||
fi
|
||||
elif command -v apt >/dev/null 2>&1; then
|
||||
echo -e "\033[32m正在安装 $pkg,请稍后\033[0m"
|
||||
apt-get install -y "$pkg" >>"$log_file" 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "\033[31m安装 $pkg 失败,请查看日志\033[0m"
|
||||
tail -n 10 "$log_file" # 输出最后10行日志
|
||||
rm -rf $log_file
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo -e "\033[31m无法识别的系统软件包管理工具\033[0m"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# 检测服务器架构
|
||||
function IF_CHECK_CORE_ALL(){
|
||||
if [ $(arch) = "x86_64" ] || [ $(arch) = "amd64" ]; then
|
||||
ARCH_TYPE=amd64
|
||||
elif [ $(arch) = "aarch64" ] || [ $(arch) = "arm64" ]; then
|
||||
ARCH_TYPE=arm64
|
||||
SEND_ERROR "本脚本暂不支持 $(arch) 架构,或许你可以删除本段判断试试哈哈"
|
||||
exit 1
|
||||
else
|
||||
SEND_ERROR "无法识别的系统架构: $(arch)"
|
||||
exit 1
|
||||
fi
|
||||
IF_CHECK_OS
|
||||
}
|
||||
|
||||
function IF_OS_ENV(){
|
||||
# 判断 OS_TRUE=0,则退出脚本
|
||||
if [ ${OS_TRUE} -eq 0 ]; then
|
||||
SEND_ERROR "本脚本暂不支持 ${OS} ${OS_VERSION} 系统"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 检测服务器系统及版本
|
||||
function IF_CHECK_OS(){
|
||||
CHECK_OS
|
||||
OS_TRUE=1
|
||||
if [ "$OS" = "centos" ]; then
|
||||
if [ "$OS_VERSION" -ne 7 ] && [ "$OS_VERSION" -ne 8 ]; then
|
||||
OS_TRUE=0
|
||||
fi
|
||||
IF_OS_ENV
|
||||
IF_CHECK_CORE
|
||||
elif [ "$OS" = "debian" ]; then
|
||||
IF_CHECK_CORE
|
||||
elif [ "$OS" = "ubuntu" ]; then
|
||||
IF_CHECK_CORE
|
||||
else
|
||||
SEND_ERROR "无法识别的系统版本"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 检测内核版本
|
||||
function IF_CHECK_CORE(){
|
||||
CHECK_OS
|
||||
if [ ${OS} = "centos" ]; then
|
||||
# 判断内核是否低于5,如果低于5则更新内核
|
||||
if [ $(uname -r | awk -F '.' '{print $1}') -lt 5 ]; then
|
||||
IF_UPDATE_ONLINE
|
||||
else
|
||||
SEND_INFO "当前内核版本为 $(uname -r),无需更新"
|
||||
fi
|
||||
elif [ ${OS} = "ubuntu" ]; then
|
||||
if [ $(uname -r | awk -F '.' '{print $1}') -lt 6 ]; then
|
||||
IF_UPDATE_ONLINE
|
||||
else
|
||||
SEND_INFO "当前内核版本为 $(uname -r),无需更新"
|
||||
fi
|
||||
elif [ ${OS} = "debian" ]; then
|
||||
if [ ${OS_VERSION} -eq 10 ] || [ ${OS_VERSION} -eq 11 ]; then
|
||||
if [ $(uname -r | awk -F '.' '{print $1}') -lt 5 ]; then
|
||||
IF_UPDATE_ONLINE
|
||||
else
|
||||
SEND_INFO "当前内核版本为 $(uname -r),无需更新"
|
||||
fi
|
||||
elif [ ${OS_VERSION} -eq 12 ]; then
|
||||
if [ $(uname -r | awk -F '.' '{print $1}') -lt 6 ]; then
|
||||
IF_UPDATE_ONLINE
|
||||
else
|
||||
SEND_INFO "当前内核版本为 $(uname -r),无需更新"
|
||||
fi
|
||||
else
|
||||
SEND_ERROR "当前 Debian 系统 $(uname -r) 版本暂时不支持内核更新"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
SEND_ERROR "当前系统暂时不支持内核更新"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 判断在线或离线升级
|
||||
function IF_UPDATE_ONLINE(){
|
||||
while true; do
|
||||
read -p "本脚本支持 在线(o)/离线(l) 升级内核,请选择升级方式 [o(默认)/l]: " UPDATE_TYPE
|
||||
case $UPDATE_TYPE in
|
||||
o|"")
|
||||
UPDATE_TYPE=online
|
||||
SEND_INFO "您选择的升级方式为: ${UPDATE_TYPE} 在线升级"
|
||||
break
|
||||
;;
|
||||
l)
|
||||
UPDATE_TYPE=local
|
||||
SEND_INFO "您选择的升级方式为: ${UPDATE_TYPE} 离线升级"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
SEND_ERROR "输入错误,请重新输入"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
IF_UPDATE_TYPE
|
||||
}
|
||||
|
||||
# 判断升级方式
|
||||
function IF_UPDATE_TYPE(){
|
||||
if [ ${UPDATE_TYPE} = "online" ]; then
|
||||
if [ ${OS} = "centos" ]; then
|
||||
if [ ${OS_VERSION} -eq 7 ]; then
|
||||
UPDATE_CENTOS_ONLINE_7
|
||||
elif [ ${OS_VERSION} -eq 8 ]; then
|
||||
UPDATE_CENTOS_ONLINE_8
|
||||
fi
|
||||
elif [ ${OS} = "debian" ]; then
|
||||
UPDATE_DEBIAN_ONLINE
|
||||
elif [ ${OS} = "ubuntu" ]; then
|
||||
UPDATE_UBUNTU_ONLINE
|
||||
fi
|
||||
elif [ ${UPDATE_TYPE} = "local" ]; then
|
||||
if [ ${OS} = "centos" ]; then
|
||||
if [ ${OS_VERSION} -eq 7 ]; then
|
||||
UPDATE_CENTOS_LOCAL_7
|
||||
elif [ ${OS_VERSION} -eq 8 ]; then
|
||||
UPDATE_CENTOS_LOCAL_8
|
||||
fi
|
||||
elif [ ${OS} = "debian" ]; then
|
||||
UPDATE_DEBIAN_LOCAL
|
||||
elif [ ${OS} = "ubuntu" ]; then
|
||||
UPDATE_UBUNTU_LOCAL
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#选择内核版本
|
||||
function SELECT_CORE(){
|
||||
# 安装内核
|
||||
# 查看可提供升级的版本
|
||||
SEND_INFO "正在查询当前内核可升级版本"
|
||||
CHECK_COMMAND_ECHO yum list available --disablerepo='*' --enablerepo=elrepo-kernel | grep -v Loaded | grep -v Loading | grep -v "*" | grep -v Available
|
||||
|
||||
# 让用户通过输入选择版本
|
||||
if [ ${ALL_DEFAULT_YES} = true ]; then
|
||||
KERNEL_VERSION=kernel-lt
|
||||
SEND_INFO "您选择的内核版本为: ${KERNEL_VERSION}"
|
||||
else
|
||||
while true; do
|
||||
read -p "请输入您想要升级的内核版本[lt(默认)/ml]: " KERNEL_VERSION
|
||||
case $KERNEL_VERSION in
|
||||
lt|"")
|
||||
KERNEL_VERSION=kernel-lt
|
||||
SEND_INFO "您选择的内核版本为: ${KERNEL_VERSION}"
|
||||
break
|
||||
;;
|
||||
ml)
|
||||
KERNEL_VERSION=kernel-ml
|
||||
SEND_INFO "您选择的内核版本为: ${KERNEL_VERSION}"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
SEND_ERROR "输入错误,请重新输入"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# 配置内核启动顺序
|
||||
function CORE_SEQUENCE(){
|
||||
# 配置系统默认启动内核
|
||||
if [ ${ALL_DEFAULT_YES} = true ]; then
|
||||
DEFAULT_KERNEL=0
|
||||
else
|
||||
while true; do
|
||||
SEND_INFO "正在获取内核版本序号"
|
||||
awk -F \' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
|
||||
read -p "请选择系终启动默认内核序号(默认0): " DEFAULT_KERNEL
|
||||
if [ -z ${DEFAULT_KERNEL} ]; then
|
||||
DEFAULT_KERNEL=0
|
||||
break
|
||||
elif [ ${DEFAULT_KERNEL} -ge 0 ] && [ ${DEFAULT_KERNEL} -le 9 ]; then
|
||||
break
|
||||
else
|
||||
SEND_ERROR "输入错误,请重新输入"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# 设置开机启动
|
||||
SEND_INFO "正在设置开机启动,请稍后"
|
||||
grub2-set-default ${DEFAULT_KERNEL}
|
||||
REBOOT
|
||||
}
|
||||
|
||||
function REBOOT(){
|
||||
if [ ${ALL_DEFAULT_YES} = true ]; then
|
||||
SEND_INFO "正在重启系统,请稍后"
|
||||
reboot
|
||||
else
|
||||
while true; do
|
||||
read -p "是否重启系统[y(默认)/n]: " REBOOT
|
||||
case $REBOOT in
|
||||
y|"")
|
||||
SEND_INFO "正在重启系统,请稍后"
|
||||
reboot
|
||||
break
|
||||
;;
|
||||
n)
|
||||
SEND_INFO "请手动重启系统"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
SEND_ERROR "输入错误,请重新输入"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
}
|
||||
# 升级 CentOS 内核
|
||||
function UPDATE_CENTOS_ONLINE_7(){
|
||||
SEND_INFO "正在加载 Kernel 源,请稍后"
|
||||
# 载入公钥
|
||||
CHECK_COMMAND_NULL rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
|
||||
|
||||
# 安装 ELRepo 源
|
||||
NULL_TRUE rpm -Uvh https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
|
||||
|
||||
SELECT_CORE
|
||||
# 安装内核
|
||||
SEND_INFO "正在安装内核,请稍后"
|
||||
CHECK_COMMAND_ECHO yum --enablerepo=elrepo-kernel install ${KERNEL_VERSION} -y
|
||||
CORE_SEQUENCE
|
||||
}
|
||||
|
||||
function UPDATE_CENTOS_LOCAL_7(){
|
||||
CHECK_FILES kernel-*.rpm
|
||||
SEND_INFO "正在安装本地内核包,请稍后"
|
||||
CHECK_COMMAND_ECHO yum localinstall -y kernel-*.rpm
|
||||
CORE_SEQUENCE
|
||||
}
|
||||
|
||||
function UPDATE_CENTOS_ONLINE_8(){
|
||||
SEND_INFO "正在加载 Kernel 源,请稍后"
|
||||
# 载入公钥
|
||||
CHECK_COMMAND_NULL rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
|
||||
|
||||
# 安装 ELRepo 源
|
||||
NULL_TRUE rpm -Uvh https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm
|
||||
|
||||
SELECT_CORE
|
||||
# 安装内核
|
||||
SEND_INFO "正在安装内核,请稍后"
|
||||
CHECK_COMMAND_ECHO yum --enablerepo=elrepo-kernel install ${KERNEL_VERSION} -y
|
||||
CORE_SEQUENCE
|
||||
}
|
||||
|
||||
function UPDATE_CENTOS_LOCAL_8(){
|
||||
UPDATE_CENTOS_LOCAL_7
|
||||
}
|
||||
|
||||
function UPDATE_UBUNTU_ONLINE(){
|
||||
SEND_INFO "正在获取内核版本,请稍后"
|
||||
VERSION=$(./ubuntu-mainline-kernel.sh -c | grep A | grep -o 'v[0-9]\+\(\.[0-9]\+\)\{2\}')
|
||||
SEND_INFO "最新稳定版本为: ${VERSION}"
|
||||
SEND_INFO "正在安装内核,请稍后"
|
||||
curl -sS https://raw.githubusercontent.com/pimlie/ubuntu-mainline-kernel.sh/master/ubuntu-mainline-kernel.sh | bash -s -- -i ${VERSION}
|
||||
CHECK_COMMAND_TRUE "安装成功" "安装失败请查看日志"
|
||||
REBOOT
|
||||
|
||||
# # 第二种更新方式
|
||||
# sudo apt update
|
||||
# apt search linux-image
|
||||
# apt-get upgrade linux-image-generic
|
||||
}
|
||||
|
||||
function UPDATE_UBUNTU_LOCAL(){
|
||||
CHECK_FILES *.deb
|
||||
SEND_INFO "正在安装本地内核包,请稍后"
|
||||
CHECK_COMMAND_ECHO dpkg --install *.deb
|
||||
REBOOT
|
||||
}
|
||||
|
||||
function UPDATE_DEBIAN_ONLINE(){
|
||||
# apt search linux-image
|
||||
CHECK_COMMAND_ECHO echo "deb http://deb.debian.org/debian buster-backports main" > /etc/apt/sources.list.d/backports.list
|
||||
CHECK_COMMAND_ECHO apt update
|
||||
CHECK_COMMAND_ECHO apt -t buster-backports install linux-image-amd64 -y
|
||||
CHECK_COMMAND_TRUE "linux-image 安装成功" "安装失败请查看日志"
|
||||
CHECK_COMMAND_ECHO apt -t buster-backports install linux-headers-amd64 -y
|
||||
CHECK_COMMAND_TRUE "linux-headers 安装成功" "安装失败请查看日志"
|
||||
SEND_INFO "正在更新开机启动顺序,请稍后"
|
||||
CHECK_COMMAND_TRUE update-grub
|
||||
REBOOT
|
||||
}
|
||||
|
||||
function UPDATE_DEBIAN_LOCAL(){
|
||||
SEND_ERROR "暂不支持 Debian 离线升级内核,有需求就提个 issue 吧"
|
||||
}
|
||||
|
||||
function ALL(){
|
||||
CHECK_NETWORK
|
||||
# 加载检测脚本
|
||||
source <(curl -sS https://gitee.com/offends/Linux/raw/main/File/Shell/Check_command.sh)
|
||||
CHECK_PARAMETER $@
|
||||
FUNC_PRINT_SYSTEM_INFO
|
||||
IF_CHECK_CORE_ALL
|
||||
}
|
||||
|
||||
# 检测外部是否传入参数
|
||||
function CHECK_PARAMETER(){
|
||||
if [ "$#" -eq 0 ] || [ "$#" -eq 1 ]; then
|
||||
case $1 in
|
||||
ALL_DEFAULT_YES=1)
|
||||
ALL_DEFAULT_YES=true
|
||||
;;
|
||||
*)
|
||||
if [ "$#" -eq 1 ]; then
|
||||
SEND_ERROR "输入参数错误,请查看帮助文档: https://gitee.com/offends/Linux/blob/main/%E8%84%9A%E6%9C%AC/README.md"
|
||||
exit 1
|
||||
fi
|
||||
ALL_DEFAULT_YES=false
|
||||
;;
|
||||
esac
|
||||
else
|
||||
SEND_ERROR "输入参数错误,请查看帮助文档: https://gitee.com/offends/Linux/blob/main/%E8%84%9A%E6%9C%AC/README.md"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
ALL $@
|
74
File/Shell/button.sh
Normal file
74
File/Shell/button.sh
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
#############################################################################################
|
||||
# 用途: Shell模拟按钮
|
||||
# 作者: 丁辉
|
||||
# 编写时间: 2024-05-20
|
||||
#############################################################################################
|
||||
|
||||
function Button() {
|
||||
# 定义选项列表
|
||||
options=("选项一" "选项二")
|
||||
|
||||
# 初始化选项索引
|
||||
selected_index=0
|
||||
|
||||
# 清除屏幕
|
||||
clear
|
||||
|
||||
# 显示选项列表
|
||||
display_options() {
|
||||
for i in "${!options[@]}"; do
|
||||
if [ $i -eq $selected_index ]; then
|
||||
echo "> ${options[i]}"
|
||||
else
|
||||
echo " ${options[i]}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# 循环直到用户选择退出
|
||||
while true; do
|
||||
display_options
|
||||
|
||||
# 读取用户输入
|
||||
read -r -sn 1 key
|
||||
|
||||
# 处理用户输入
|
||||
case $key in
|
||||
"A") # 上箭头
|
||||
if [ $selected_index -gt 0 ]; then
|
||||
selected_index=$((selected_index - 1))
|
||||
fi
|
||||
;;
|
||||
"B") # 下箭头
|
||||
if [ $selected_index -lt $(( ${#options[@]} - 1 )) ]; then
|
||||
selected_index=$((selected_index + 1))
|
||||
fi
|
||||
;;
|
||||
""|" ") # 回车键或空格键
|
||||
break
|
||||
;;
|
||||
"q") # 按 'q' 键退出
|
||||
clear
|
||||
echo "退出"
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
|
||||
# 清除屏幕
|
||||
clear
|
||||
done
|
||||
|
||||
# 用户选择的选项
|
||||
selected_option="${options[selected_index]}"
|
||||
send_info $selected_option
|
||||
|
||||
if [ "$selected_option" == "选项一" ]; then
|
||||
echo "选项一"
|
||||
elif [ "$selected_option" == "选项二" ]; then
|
||||
echo "选项二"
|
||||
fi
|
||||
}
|
||||
|
||||
Button
|
37
File/Shell/cgroup.sh
Normal file
37
File/Shell/cgroup.sh
Normal file
@@ -0,0 +1,37 @@
|
||||
set -e
|
||||
# 这句是告诉bash如何有任何语句执行结果不为ture,就应该退出。
|
||||
|
||||
if grep -v '^#' /etc/fstab | grep -q cgroup; then
|
||||
echo 'cgroups mounted from fstab, not mounting /sys/fs/cgroup'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# kernel provides cgroups?
|
||||
if [ ! -e /proc/cgroups ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 确保目录存在
|
||||
if [ ! -d /sys/fs/cgroup ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# mount /sys/fs/cgroup if not already done
|
||||
if ! mountpoint -q /sys/fs/cgroup; then
|
||||
mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup
|
||||
fi
|
||||
|
||||
cd /sys/fs/cgroup
|
||||
|
||||
# get/mount list of enabled cgroup controllers
|
||||
for sys in $(awk '!/^#/ { if ($4 == 1) print $1 }' /proc/cgroups); do
|
||||
mkdir -p $sys
|
||||
if ! mountpoint -q $sys; then
|
||||
if ! mount -n -t cgroup -o $sys cgroup $sys; then
|
||||
rmdir $sys || true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
exit 0
|
21
File/Shell/check-cpu-sysstat.sh
Normal file
21
File/Shell/check-cpu-sysstat.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
#############################################################################################
|
||||
# 用途: 使用 Sysstat 工具检测 CPU 负载
|
||||
# 作者: 丁辉
|
||||
# 更新时间: 2024-05-10
|
||||
#############################################################################################
|
||||
|
||||
# 获取 CPU 使用情况
|
||||
cpu_usage=$(mpstat 1 1 | awk '/Average:/ {print 100 - $12}')
|
||||
|
||||
# 输出 CPU 使用率
|
||||
echo "当前 CPU 使用率为: $cpu_usage%"
|
||||
|
||||
# 根据需要设置 CPU 使用率的阈值
|
||||
threshold=80
|
||||
|
||||
# 检查 CPU 使用率是否超过阈值
|
||||
if (( $(echo "$cpu_usage > $threshold" | bc -l) )); then
|
||||
echo "警告: CPU 使用率超过 ${threshold}%!"
|
||||
fi
|
48
File/Shell/check-cpu.sh
Normal file
48
File/Shell/check-cpu.sh
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
|
||||
#############################################################################################
|
||||
# 用途: 检测 CPU 负载
|
||||
# 作者: 丁辉
|
||||
# 更新时间: 2024-05-10
|
||||
#############################################################################################
|
||||
|
||||
# 获取第一次 CPU 时间统计
|
||||
read -a stats1 < /proc/stat
|
||||
|
||||
# 第一次统计的总 CPU 时间
|
||||
total1=0
|
||||
for i in {1..4}; do
|
||||
total1=$((total1 + ${stats1[i]}))
|
||||
done
|
||||
|
||||
# 第一次统计的空闲 CPU 时间
|
||||
idle1=${stats1[4]}
|
||||
|
||||
# 等待一个时间间隔
|
||||
sleep 1
|
||||
|
||||
# 获取第二次 CPU 时间统计
|
||||
read -a stats2 < /proc/stat
|
||||
|
||||
# 第二次统计的总 CPU 时间
|
||||
total2=0
|
||||
for i in {1..4}; do
|
||||
total2=$((total2 + ${stats2[i]}))
|
||||
done
|
||||
|
||||
# 第二次统计的空闲 CPU 时间
|
||||
idle2=${stats2[4]}
|
||||
|
||||
# 计算总的 CPU 时间差和空闲 CPU 时间差
|
||||
total=$((total2 - total1))
|
||||
idle=$((idle2 - idle1))
|
||||
|
||||
# 避免除零错误
|
||||
if [ $total -ne 0 ]; then
|
||||
cpu_usage=$((100 * (total - idle) / total))
|
||||
else
|
||||
cpu_usage=0
|
||||
fi
|
||||
|
||||
# 输出 CPU 使用率
|
||||
echo "当前 CPU 使用率为: $cpu_usage%"
|
27
File/Shell/mysql-backup.sh
Normal file
27
File/Shell/mysql-backup.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
#############################################################################################
|
||||
# 用途: Mysql 数据库备份脚本
|
||||
# 作者: 丁辉
|
||||
# 更新时间: 2024-05-20
|
||||
#############################################################################################
|
||||
|
||||
# crontab -e
|
||||
# 0 2 * * * bash /opt/mysql/backup/mysql-backup.sh
|
||||
|
||||
MYSQL_HOST=<MYSQL_HOST>
|
||||
MYSQL_USER=root
|
||||
MYSQL_PASS=root
|
||||
BACKDIRPATH=/opt/mysql/backup
|
||||
DATE=`date +%F%H%M`
|
||||
|
||||
# 填写需要备份的数据库
|
||||
databases=(
|
||||
database
|
||||
)
|
||||
|
||||
for DATABASE in ${databases[@]};do
|
||||
docker run --rm mysql:8.0 mysqldump -h${MYSQL_HOST} -u${MYSQL_USER} -p${MYSQL_PASS} ${DATABASE} > ${BACKDIRPATH}/${DATABASE}-${DATE}.sql
|
||||
tar zcf ${BACKDIRPATH}/${DATABASE}-${DATE}.tar ${BACKDIRPATH}/${DATABASE}-${DATE}.sql
|
||||
done
|
||||
find ${BACKUP_DIR} -name "rainbond-*.sql.gz" -type f -mtime +30 -exec rm {} \; > /dev/null 2>&1
|
39
File/Shell/nginx-ssl.sh
Normal file
39
File/Shell/nginx-ssl.sh
Normal file
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
|
||||
#############################################################################################
|
||||
# 用途: Nginx 签发证书脚本
|
||||
# 作者: 丁辉
|
||||
# 更新时间: 2024-05-20
|
||||
#############################################################################################
|
||||
|
||||
read -p "输入您的域名: " DOMAIN
|
||||
|
||||
echo "创建服务器密钥..."
|
||||
|
||||
openssl genrsa -des3 -out $DOMAIN.key 1024
|
||||
|
||||
echo "创建服务器证书签名请求..."
|
||||
|
||||
SUBJECT="/C=US/ST=Mars/L=iTranswarp/O=iTranswarp/OU=iTranswarp/CN=$DOMAIN"
|
||||
|
||||
openssl req -new -subj $SUBJECT -key $DOMAIN.key -out $DOMAIN.csr
|
||||
|
||||
echo "移除密码..."
|
||||
|
||||
mv $DOMAIN.key $DOMAIN.origin.key
|
||||
openssl rsa -in $DOMAIN.origin.key -out $DOMAIN.key
|
||||
|
||||
echo "签署SSL证书..."
|
||||
|
||||
openssl x509 -req -days 3650 -in $DOMAIN.csr -signkey $DOMAIN.key -out $DOMAIN.crt
|
||||
|
||||
echo "待办事项: "
|
||||
echo "将 $DOMAIN.crt 复制到 /etc/nginx/ssl/$DOMAIN.crt"
|
||||
echo "将 $DOMAIN.key 复制到 /etc/nginx/ssl/$DOMAIN.key"
|
||||
echo "在nginx中添加配置:"
|
||||
echo "server {"
|
||||
echo " ..."
|
||||
echo " listen 443 ssl;"
|
||||
echo " ssl_certificate /etc/nginx/ssl/$DOMAIN.crt;"
|
||||
echo " ssl_certificate_key /etc/nginx/ssl/$DOMAIN.key;"
|
||||
echo "}"
|
71
File/Shell/openssl-cert.sh
Normal file
71
File/Shell/openssl-cert.sh
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
|
||||
#############################################################################################
|
||||
# 用途: 生成 Docker 远程证书生成脚本
|
||||
# 作者: 丁辉
|
||||
# 编写时间: 2024-01-03
|
||||
#############################################################################################
|
||||
|
||||
# 加载检测脚本
|
||||
source <(curl -sS https://gitee.com/offends/Shell/raw/main/Check_command.sh)
|
||||
|
||||
# 定义变量
|
||||
IP="127.0.0.1"
|
||||
PASSWORD="123456"
|
||||
VALIDITY_PERIOD=3650
|
||||
|
||||
SEND_INFO "开始生成 Docker 远程证书,请稍等..."
|
||||
|
||||
CHECK_DIR "/usr/local/ca"
|
||||
|
||||
cd /usr/local/ca
|
||||
|
||||
# 生成 CA 私钥
|
||||
openssl genrsa -aes256 -passout pass:"$PASSWORD" -out ca-key.pem 4096
|
||||
|
||||
# 生成 CA 证书
|
||||
openssl req -new -x509 -days $VALIDITY_PERIOD -key ca-key.pem -passin pass:"$PASSWORD" -sha256 -out ca.pem -subj "/C=CN/ST=./L=./O=./CN=$IP"
|
||||
|
||||
# 生成服务器私钥
|
||||
openssl genrsa -out server-key.pem 4096
|
||||
|
||||
# 生成服务器证书签名请求
|
||||
openssl req -subj "/CN=$IP" -sha256 -new -key server-key.pem -out server.csr
|
||||
|
||||
# 生成服务器证书
|
||||
echo subjectAltName = IP:$IP,IP:0.0.0.0 >> server.cnf
|
||||
|
||||
openssl x509 -req -days $VALIDITY_PERIOD -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -passin "pass:$PASSWORD" -CAcreateserial -out server-cert.pem -extfile server.cnf
|
||||
|
||||
# 生成客户端私钥
|
||||
openssl genrsa -out key.pem 4096
|
||||
|
||||
# 生成客户端证书签名请求
|
||||
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
|
||||
|
||||
# 生成客户端证书
|
||||
echo extendedKeyUsage = clientAuth >> server.cnf
|
||||
|
||||
echo extendedKeyUsage = clientAuth > server-client.cnf
|
||||
|
||||
openssl x509 -req -days $VALIDITY_PERIOD -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -passin "pass:$PASSWORD" -CAcreateserial -out cert.pem -extfile server-client.cnf
|
||||
|
||||
# 清理文件
|
||||
rm -rf client.csr server.csr server.cnf server-client.cnf
|
||||
|
||||
# 修改权限
|
||||
chmod 0400 ca-key.pem key.pem server-key.pem
|
||||
|
||||
chmod 0444 ca.pem server-cert.pem cert.pem
|
||||
|
||||
SEND_INFO "Docker 远程证书生成完毕,正在移动目录请稍等..."
|
||||
|
||||
CHECK_DIR "/etc/docker/cert/2375/"
|
||||
|
||||
cp server-*.pem /etc/docker/cert/2375/
|
||||
|
||||
cp ca.pem /etc/docker/cert/2375/
|
||||
|
||||
rm -rf /usr/local/ca/
|
||||
|
||||
SEND_INFO "Docker 远程证书移动完毕,请手动配置 Docker 远程证书路径为 /etc/docker/cert/2375/"
|
85
File/Shell/rsync_inotify.sh
Normal file
85
File/Shell/rsync_inotify.sh
Normal file
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
|
||||
#############################################################################################
|
||||
# 用途: inotify 同步脚本
|
||||
# 作者: 丁辉
|
||||
# 更新时间: 2024-03-28
|
||||
#############################################################################################
|
||||
|
||||
# rsync 服务端 IP
|
||||
HOST=none
|
||||
# rsync 用户名
|
||||
USER=rsync
|
||||
# rsync 密码文件
|
||||
PASSWORD=/etc/rsync.pass
|
||||
# 同步目录
|
||||
SRC=/data/
|
||||
# rsync 模块
|
||||
Module=data
|
||||
# inotifywait 命令
|
||||
inotifywait=/usr/bin/inotifywait
|
||||
|
||||
#### Inotifywait 参数解释
|
||||
# -m: 监控目录
|
||||
# -r: 递归监控
|
||||
# -q: 静默模式
|
||||
# --timefmt: 时间格式
|
||||
# %Y: 年
|
||||
# %m: 月
|
||||
# %d: 日
|
||||
# %H: 时
|
||||
# %M: 分
|
||||
# --format: 输出格式
|
||||
# %T: 时间
|
||||
# %w: 目录
|
||||
# %f: 文件
|
||||
# %e: 事件
|
||||
# %Xe: 扩展事件
|
||||
# -e: 监控事件
|
||||
# modify: 文件内容修改
|
||||
# delete: 文件删除
|
||||
# create: 文件创建
|
||||
# attrib: 文件属性修改
|
||||
# move: 文件移动
|
||||
# close_write: 文件关闭写入
|
||||
|
||||
##### Rsync 参数解释
|
||||
# -a: 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于-rlptgoD
|
||||
# -r: 相对路径传输文件
|
||||
# -t: 保持文件时间信息
|
||||
# -u: 仅传输更新文件
|
||||
# -z: 传输时压缩
|
||||
# -v: 详细模式输出
|
||||
# -c: 跳过校验算法,仅根据文件时间和大小判断是否同步
|
||||
# -P: 保持文件传输进度
|
||||
|
||||
# 监控目录
|
||||
cd $SRC
|
||||
|
||||
$inotifywait -mrq --timefmt '%Y%m%d %H:%M' --format '%T %w%f %Xe' -e modify,delete,create,attrib,move,close_write ./ \
|
||||
| while read files ;do
|
||||
# 获取文件路径
|
||||
FILE_PWD=$(echo $files | awk '{print $3}')
|
||||
# 获取文件事件
|
||||
FILE_EVENT=$(echo $files | awk '{print $4}')
|
||||
# 在日志内提示时间
|
||||
echo ".....................................$(date)....................................."
|
||||
|
||||
# 增加、修改、写入完成、移动进事件
|
||||
if [[ $FILE_EVENT =~ "CREATE" ]] || [[ $FILE_EVENT =~ "MODIFY" ]] || [[ $FILE_EVENT =~ "CLOSE_WRITE" ]] || [[ $FILE_EVENT =~ "MOVED_TO" ]]; then
|
||||
rsync -artuz --password-file=${PASSWORD} $(dirname ${FILE_PWD}) ${USER}@${HOST}::${Module}
|
||||
fi
|
||||
|
||||
# 删除、移动事件触发
|
||||
if [[ $FILE_EVENT =~ "DELETE" ]] || [[ $FILE_EVENT =~ "MOVED_FROM" ]]; then
|
||||
rsync -artuz --password-file=${PASSWORD} $(dirname ${FILE_PWD}) ${USER}@${HOST}::${Module}
|
||||
fi
|
||||
|
||||
# 修改属性事件触发[ touch, chgrp, chmod, chown ]
|
||||
if [[ $FILE_EVENT =~ "ATTRIB" ]]; then
|
||||
# 判断是否为目录, 如果是目录则不同步(在目录下文件修改属性时, 目录属性也会被修改)
|
||||
if [ ! -d "$INO_FILE" ]; then
|
||||
rsync -artuz --password-file=${PASSWORD} $(dirname ${FILE_PWD}) ${USER}@${HOST}::${Module}
|
||||
fi
|
||||
fi
|
||||
done
|
921
File/Shell/ubuntu-mainline-kernel.sh
Normal file
921
File/Shell/ubuntu-mainline-kernel.sh
Normal file
@@ -0,0 +1,921 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# shellcheck disable=SC1117
|
||||
|
||||
# Ubuntu Kernel PPA info
|
||||
ppa_host="kernel.ubuntu.com"
|
||||
ppa_index="/~kernel-ppa/mainline/"
|
||||
ppa_key="17C622B0"
|
||||
|
||||
# Machine-Owner-Key for Secure Boot
|
||||
sign_kernel=0
|
||||
mokKey="/var/lib/shim-signed/mok/MOK-Kernel.priv"
|
||||
mokCert="/var/lib/shim-signed/mok/MOK-Kernel.pem"
|
||||
|
||||
self_update_url="https://raw.githubusercontent.com/pimlie/ubuntu-mainline-kernel.sh/master/ubuntu-mainline-kernel.sh"
|
||||
|
||||
# If quiet=1 then no log messages are printed (except errors)
|
||||
quiet=0
|
||||
|
||||
# If check_signature=0 then the signature of the CHECKSUMS file will not be checked
|
||||
check_signature=1
|
||||
|
||||
# If check_checksum=0 then the checksums of the .deb files will not be checked
|
||||
check_checksum=1
|
||||
|
||||
# If doublecheckversion=1 then also check the version specific ppa page to make
|
||||
# sure the kernel build was successful
|
||||
doublecheckversion=1
|
||||
|
||||
# Connect over http or https to ppa (only https works)
|
||||
use_https=1
|
||||
|
||||
# Path to sudo command, empty by default
|
||||
sudo=""
|
||||
#sudo=$(command -v sudo) # Uncomment this line if you dont want to sudo yourself
|
||||
|
||||
# Path to wget command
|
||||
wget=$(command -v wget)
|
||||
|
||||
#####
|
||||
## Below are internal variables of which most can be toggled by command options
|
||||
## DON'T CHANGE THESE MANUALLY
|
||||
#####
|
||||
|
||||
# (internal) If cleanup_files=1 then before exiting all downloaded/temporaryfiles
|
||||
# are removed
|
||||
cleanup_files=1
|
||||
|
||||
# (internal) If do_install=0 downloaded deb files will not be installed
|
||||
do_install=1
|
||||
|
||||
# (internal) If use_lowlatency=1 then the lowlatency kernel will be installed
|
||||
use_lowlatency=0
|
||||
|
||||
# (internal) If use_lpae=1 then the lpae kernel will be installed
|
||||
use_lpae=0
|
||||
|
||||
# (internal) If use_snapdragon=1 then the snapdragon kernel will be installed
|
||||
use_snapdragon=0
|
||||
|
||||
# (internal) If use_rc=1 then release candidate kernel versions are also checked
|
||||
use_rc=0
|
||||
|
||||
# (internal) If assume_yes=1 assume yes on all prompts
|
||||
assume_yes=0
|
||||
|
||||
# (internal) How many files we expect to retrieve from the ppa
|
||||
# checksum, signature, header-all, header-arch, image(-unsigned), modules
|
||||
expected_files_count=6
|
||||
|
||||
# (internal) Which action/command the script should run
|
||||
run_action="help"
|
||||
|
||||
# (internal) The workdir where eg the .deb files are downloaded
|
||||
workdir="/tmp/$(basename "$0")/"
|
||||
|
||||
# (internal) The stdio where all detail output should be sent
|
||||
debug_target="/dev/null"
|
||||
|
||||
# (internal) Holds all version numbers of locally installed ppa kernels
|
||||
LOCAL_VERSIONS=()
|
||||
|
||||
# (internal) Holds all version numbers of available ppa kernels
|
||||
REMOTE_VERSIONS=()
|
||||
|
||||
# (internal) The architecture of the local system
|
||||
arch=$(dpkg --print-architecture)
|
||||
|
||||
# (internal) The text to search for to check if the build was successfully
|
||||
# NOTE: New succeed text since v5.6.18
|
||||
build_succeeded_text="(Build for ${arch} succeeded|Test ${arch}/build succeeded)"
|
||||
|
||||
# (internal) The pid of the child process which checks download progress
|
||||
monitor_pid=0
|
||||
|
||||
# (internal) The size of the file which is being downloaded
|
||||
download_size=0
|
||||
|
||||
action_data=()
|
||||
|
||||
#####
|
||||
## Check if we are running on an Ubuntu-like OS
|
||||
#####
|
||||
|
||||
# shellcheck disable=SC1091,SC2015
|
||||
[ -f "/etc/os-release" ] && {
|
||||
source /etc/os-release
|
||||
[[ "$ID" == "ubuntu" ]] || [[ "$ID_LIKE" =~ "ubuntu" ]]
|
||||
} || {
|
||||
OS=$(lsb_release -si 2>&-)
|
||||
[[ "$OS" == "Ubuntu" ]] || [[ "$OS" == "LinuxMint" ]] || [[ "$OS" == "neon" ]] || {
|
||||
echo "Abort, this script is only intended for Ubuntu-like distros"
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
|
||||
#####
|
||||
## helper functions
|
||||
#####
|
||||
|
||||
single_action () {
|
||||
[ "$run_action" != "help" ] && {
|
||||
err "Abort, only one argument can be supplied. See -h"
|
||||
exit 2
|
||||
}
|
||||
}
|
||||
|
||||
log () {
|
||||
[ $quiet -eq 0 ] && echo "$@"
|
||||
}
|
||||
|
||||
logn () {
|
||||
[ $quiet -eq 0 ] && echo -n "$@"
|
||||
}
|
||||
|
||||
warn () {
|
||||
[ $quiet -eq 0 ] && echo "$@" >&2
|
||||
}
|
||||
|
||||
err () {
|
||||
echo "$@" >&2
|
||||
}
|
||||
|
||||
#####
|
||||
## Simple command options parser
|
||||
#####
|
||||
|
||||
while (( "$#" )); do
|
||||
argarg_required=0
|
||||
|
||||
case $1 in
|
||||
-c|--check)
|
||||
single_action
|
||||
run_action="check"
|
||||
;;
|
||||
-l|--local-list)
|
||||
single_action
|
||||
run_action="local-list"
|
||||
argarg_required=1
|
||||
;;
|
||||
-r|--remote-list)
|
||||
single_action
|
||||
run_action="remote-list"
|
||||
argarg_required=1
|
||||
;;
|
||||
-i|--install)
|
||||
single_action
|
||||
run_action="install"
|
||||
argarg_required=1
|
||||
;;
|
||||
-u|--uninstall)
|
||||
single_action
|
||||
run_action="uninstall"
|
||||
argarg_required=1
|
||||
;;
|
||||
-p|--path)
|
||||
if [ -z "$2" ] || [ "${2##-}" != "$2" ]; then
|
||||
err "Option $1 requires an argument."
|
||||
exit 2
|
||||
else
|
||||
workdir="$(realpath "$2")/"
|
||||
shift
|
||||
|
||||
if [ ! -d "$workdir" ]; then
|
||||
mkdir -p "$workdir";
|
||||
fi
|
||||
|
||||
if [ ! -d "$workdir" ] || [ ! -w "$workdir" ]; then
|
||||
err "$workdir is not writable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cleanup_files=0
|
||||
fi
|
||||
;;
|
||||
-ll|--lowlatency|--low-latency)
|
||||
[[ "$arch" != "amd64" ]] && [[ "$arch" != "i386" ]] && {
|
||||
err "Low-latency kernels are only available for amd64 or i386 architectures"
|
||||
exit 3
|
||||
}
|
||||
|
||||
use_lowlatency=1
|
||||
;;
|
||||
-lpae|--lpae)
|
||||
[[ "$arch" != "armhf" ]] && {
|
||||
err "Large Physical Address Extension (LPAE) kernels are only available for the armhf architecture"
|
||||
exit 3
|
||||
}
|
||||
|
||||
use_lpae=1
|
||||
;;
|
||||
--snapdragon)
|
||||
[[ "$arch" != "arm64" ]] && {
|
||||
err "Snapdragon kernels are only available for the arm64 architecture"
|
||||
exit 3
|
||||
}
|
||||
|
||||
use_snapdragon=1
|
||||
;;
|
||||
--rc)
|
||||
use_rc=1
|
||||
;;
|
||||
-s|--signed)
|
||||
log "The option '--signed' is not yet implemented"
|
||||
;;
|
||||
--yes)
|
||||
assume_yes=1
|
||||
;;
|
||||
-q|--quiet)
|
||||
[ "$debug_target" == "/dev/null" ] && { quiet=1; }
|
||||
;;
|
||||
-do|--download-only)
|
||||
do_install=0
|
||||
cleanup_files=0
|
||||
;;
|
||||
-ns|--no-signature)
|
||||
check_signature=0
|
||||
;;
|
||||
-nc|--no-checksum)
|
||||
check_checksum=0
|
||||
;;
|
||||
-d|--debug)
|
||||
debug_target="/dev/stderr"
|
||||
quiet=0
|
||||
;;
|
||||
--update)
|
||||
run_action="update"
|
||||
;;
|
||||
-h|--help)
|
||||
run_action="help"
|
||||
;;
|
||||
*)
|
||||
run_action="help"
|
||||
err "Unknown argument $1"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ $argarg_required -eq 1 ]; then
|
||||
[ -n "$2" ] && [ "${2##-}" == "$2" ] && {
|
||||
action_data+=("$2")
|
||||
shift
|
||||
}
|
||||
elif [ $argarg_required -eq 2 ]; then
|
||||
# shellcheck disable=SC2015
|
||||
[ -n "$2" ] && [ "${2##-}" == "$2" ] && {
|
||||
action_data+=("$2")
|
||||
shift
|
||||
} || {
|
||||
err "Option $1 requires an argument"
|
||||
exit 2
|
||||
}
|
||||
fi
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
#####
|
||||
## internal functions
|
||||
#####
|
||||
|
||||
containsElement () {
|
||||
local e
|
||||
for e in "${@:2}"; do [[ "$e" == "$1" ]] || [[ "$e" =~ $1- ]] && return 0; done
|
||||
return 1
|
||||
}
|
||||
|
||||
download () {
|
||||
host=$1
|
||||
uri=$2
|
||||
|
||||
if [ $use_https -eq 1 ]; then
|
||||
$wget -q --save-headers --output-document - "https://$host$uri"
|
||||
else
|
||||
exec 3<>/dev/tcp/"$host"/80
|
||||
echo -e "GET $uri HTTP/1.0\r\nHost: $host\r\nConnection: close\r\n\r\n" >&3
|
||||
cat <&3
|
||||
fi
|
||||
}
|
||||
|
||||
monitor_progress () {
|
||||
local msg=$1
|
||||
local file=$2
|
||||
|
||||
download_size=-1
|
||||
printf "%s: " "$msg"
|
||||
(while :; do for c in / - \\ \|; do
|
||||
[[ -f "$file" ]] && {
|
||||
# shellcheck disable=SC2015
|
||||
[[ $download_size -le 0 ]] && {
|
||||
download_size=$(($(head -n20 "$file" | grep -aoi -E "Content-Length: [0-9]+" | cut -d" " -f2) + 0))
|
||||
printf ' %d%% %s' 0 "$c"
|
||||
printf '\b%.0s' {1..5}
|
||||
} || {
|
||||
filesize=$(( $(du -b "$file" | cut -f1) + 0))
|
||||
progress="$((200*filesize/download_size % 2 + 100*filesize/download_size))"
|
||||
|
||||
printf ' %s%% %s' "$progress" "$c"
|
||||
length=$((4 + ${#progress}))
|
||||
printf '\b%.0s' $(seq 1 $length)
|
||||
}
|
||||
}
|
||||
sleep 1
|
||||
done; done) &
|
||||
monitor_pid=$!
|
||||
}
|
||||
|
||||
end_monitor_progress () {
|
||||
{ kill $monitor_pid && wait $monitor_pid; printf '100%% \n'; } 2>/dev/null
|
||||
}
|
||||
|
||||
remove_http_headers () {
|
||||
file="$1"
|
||||
nr=0
|
||||
while(true); do
|
||||
nr=$((nr + 1))
|
||||
line=$(head -n$nr "$file" | tail -n 1)
|
||||
|
||||
if [ -z "$(echo "$line" | tr -cd '\r\n')" ]; then
|
||||
tail -n +$nr "$file" > "${file}.tmp"
|
||||
mv "${file}.tmp" "${file}"
|
||||
break
|
||||
fi
|
||||
|
||||
[ $nr -gt 100 ] && {
|
||||
err "Abort, could not remove http headers from file"
|
||||
exit 3
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
load_local_versions() {
|
||||
local version
|
||||
if [ ${#LOCAL_VERSIONS[@]} -eq 0 ]; then
|
||||
IFS=$'\n'
|
||||
for pckg in $(dpkg -l linux-image-* | cut -d " " -f 3 | sort -V); do
|
||||
# only match kernels from ppa
|
||||
if [[ "$pckg" =~ linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]{6} ]]; then
|
||||
version="v"$(echo "$pckg" | cut -d"-" -f 3,4)
|
||||
|
||||
LOCAL_VERSIONS+=("$version")
|
||||
fi
|
||||
done
|
||||
unset IFS
|
||||
fi
|
||||
}
|
||||
|
||||
latest_local_version() {
|
||||
load_local_versions 1
|
||||
|
||||
if [ ${#LOCAL_VERSIONS[@]} -gt 0 ]; then
|
||||
local sorted
|
||||
mapfile -t sorted < <(echo "${LOCAL_VERSIONS[*]}" | tr ' ' '\n' | sort -t"." -k1V,3)
|
||||
|
||||
lv="${sorted[${#sorted[@]}-1]}"
|
||||
echo "${lv/-[0-9][0-9][0-9][0-9][0-9][0-9]rc/-rc}"
|
||||
else
|
||||
echo "none"
|
||||
fi
|
||||
}
|
||||
|
||||
remote_html_cache=""
|
||||
parse_remote_versions() {
|
||||
local line
|
||||
while read -r line; do
|
||||
if [[ $line =~ DIR.*href=\"(v[[:digit:]]+\.[[:digit:]]+(\.[[:digit:]]+)?)(-(rc[[:digit:]]+))?/\" ]]; then
|
||||
line="${BASH_REMATCH[1]}"
|
||||
if [[ -z "${BASH_REMATCH[2]}" ]]; then
|
||||
line="$line.0"
|
||||
fi
|
||||
# temporarily substitute rc suffix join character for correct version sort
|
||||
if [[ -n "${BASH_REMATCH[3]}" ]]; then
|
||||
line="$line~${BASH_REMATCH[4]}"
|
||||
fi
|
||||
echo "$line"
|
||||
fi
|
||||
done <<<"$remote_html_cache"
|
||||
}
|
||||
|
||||
load_remote_versions () {
|
||||
local line
|
||||
|
||||
[[ -n "$2" ]] && {
|
||||
REMOTE_VERSIONS=()
|
||||
}
|
||||
|
||||
if [ ${#REMOTE_VERSIONS[@]} -eq 0 ]; then
|
||||
if [ -z "$remote_html_cache" ]; then
|
||||
[ -z "$1" ] && logn "Downloading index from $ppa_host"
|
||||
remote_html_cache=$(download $ppa_host $ppa_index)
|
||||
[ -z "$1" ] && log
|
||||
fi
|
||||
|
||||
if [ -n "$remote_html_cache" ]; then
|
||||
IFS=$'\n'
|
||||
while read -r line; do
|
||||
# reinstate original rc suffix join character
|
||||
if [[ $line =~ ^([^~]+)~([^~]+)$ ]]; then
|
||||
[[ $use_rc -eq 0 ]] && continue
|
||||
line="${BASH_REMATCH[1]}-${BASH_REMATCH[2]}"
|
||||
fi
|
||||
[[ -n "$2" ]] && [[ ! "$line" =~ $2 ]] && continue
|
||||
REMOTE_VERSIONS+=("$line")
|
||||
done < <(parse_remote_versions | sort -V)
|
||||
unset IFS
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
latest_remote_version () {
|
||||
load_remote_versions 1 "$1"
|
||||
|
||||
if [ ${#REMOTE_VERSIONS[@]} -gt 0 ]; then
|
||||
echo "${REMOTE_VERSIONS[${#REMOTE_VERSIONS[@]}-1]}"
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
check_environment () {
|
||||
if [ $use_https -eq 1 ] && [ -z "$wget" ]; then
|
||||
err "Abort, wget not found. Please apt install wget"
|
||||
exit 3
|
||||
fi
|
||||
}
|
||||
|
||||
guard_run_as_root () {
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "The '$run_action' command requires root privileges"
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
# execute requested action
|
||||
case $run_action in
|
||||
help)
|
||||
echo "Usage: $0 -c|-l|-r|-u
|
||||
|
||||
Download & install the latest kernel available from $ppa_host$ppa_uri
|
||||
|
||||
Arguments:
|
||||
-c Check if a newer kernel version is available
|
||||
-i [VERSION] Install kernel VERSION, see -l for list. You don't have to prefix
|
||||
with v. E.g. -i 4.9 is the same as -i v4.9. If version is
|
||||
omitted the latest available version will be installed
|
||||
-l [SEARCH] List locally installed kernel versions. If an argument to this
|
||||
option is supplied it will search for that
|
||||
-r [SEARCH] List available kernel versions. If an argument to this option
|
||||
is supplied it will search for that
|
||||
-u [VERSION] Uninstall the specified kernel version. If version is omitted,
|
||||
a list of max 10 installed kernel versions is displayed
|
||||
--update Update this script by redownloading it from github
|
||||
-h Show this message
|
||||
|
||||
Optional:
|
||||
-s, --signed Only install signed kernel packages (not implemented)
|
||||
-p, --path DIR The working directory, .deb files will be downloaded into
|
||||
this folder. If omitted, the folder /tmp/$(basename "$0")/
|
||||
is used. Path is relative from \$PWD
|
||||
-ll, --low-latency Use the low-latency version of the kernel, only for amd64 & i386
|
||||
-lpae, --lpae Use the Large Physical Address Extension kernel, only for armhf
|
||||
--snapdragon Use the Snapdragon kernel, only for arm64
|
||||
-do, --download-only Only download the deb files, do not install them
|
||||
-ns, --no-signature Do not check the gpg signature of the checksums file
|
||||
-nc, --no-checksum Do not check the sha checksums of the .deb files
|
||||
-d, --debug Show debug information, all internal command's echo their output
|
||||
--rc Also include release candidates
|
||||
--yes Assume yes on all questions (use with caution!)
|
||||
"
|
||||
exit 2
|
||||
;;
|
||||
update)
|
||||
check_environment
|
||||
|
||||
self="$(readlink -f "$0")"
|
||||
$wget -q -O "$self.tmp" "$self_update_url"
|
||||
|
||||
if [ ! -s "$self.tmp" ]; then
|
||||
rm "$self.tmp"
|
||||
err "Update failed, downloaded file is empty"
|
||||
exit 1
|
||||
else
|
||||
mv "$self.tmp" "$self"
|
||||
echo "Script updated"
|
||||
fi
|
||||
;;
|
||||
check)
|
||||
check_environment
|
||||
|
||||
logn "Finding latest version available on $ppa_host"
|
||||
latest_version=$(latest_remote_version)
|
||||
log ": $latest_version"
|
||||
|
||||
if [ -z "$latest_version" ]; then
|
||||
err "Could not find latest version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
logn "Finding latest installed version"
|
||||
installed_version=$(latest_local_version)
|
||||
installed_version=${installed_version%-*}
|
||||
log ": $installed_version"
|
||||
|
||||
# Check if build was successful
|
||||
if [ $doublecheckversion -gt 0 ]; then
|
||||
ppa_uri=$ppa_index${latest_version%\.0}"/"
|
||||
ppa_uri=${ppa_uri/\.0-rc/-rc}
|
||||
|
||||
index=$(download $ppa_host "$ppa_uri")
|
||||
if [[ ! $index =~ $build_succeeded_text ]]; then
|
||||
log "A newer kernel version ($latest_version) was found but the build was not successful"
|
||||
|
||||
[ -n "$DISPLAY" ] && [ -x "$(command -v notify-send)" ] && notify-send --icon=info -t 12000 \
|
||||
"Kernel $latest_version available" \
|
||||
"A newer kernel version ($latest_version) is\navailable but the build was not successful"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check installed minor branch
|
||||
latest_minor_text=""
|
||||
latest_minor_notify=""
|
||||
latest_minor_version=""
|
||||
if [ -n "${installed_version}" ] && [ "${installed_version}" != "none" ] && [ "${latest_version%.*}" != "${installed_version%.*}" ]; then
|
||||
latest_minor_version=$(latest_remote_version "${installed_version%.*}")
|
||||
|
||||
if [ "$installed_version" != "$latest_minor_version" ]; then
|
||||
latest_minor_text=", latest in current branch is ${latest_minor_version}"
|
||||
latest_minor_notify="Version ${latest_minor_version} is available in the current ${installed_version%.*} branch\n\n"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$installed_version" != "$latest_version" ] && [ "$installed_version" = "$(echo -e "$latest_version\n$installed_version" | sort -V | head -n1)" ]; then
|
||||
log "A newer kernel version ($latest_version) is available${latest_minor_text}"
|
||||
|
||||
[ -n "$DISPLAY" ] && [ -x "$(command -v notify-send)" ] && notify-send --icon=info -t 12000 \
|
||||
"Kernel $latest_version available" \
|
||||
"A newer kernel version ($latest_version) is available\n\n${latest_minor_notify}Run '$(basename "$0") -i' to update\nor visit $ppa_host$ppa_uri"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
local-list)
|
||||
load_local_versions
|
||||
|
||||
# shellcheck disable=SC2015
|
||||
[[ -n "$(command -v column)" ]] && { column="column -x"; } || { column="cat"; }
|
||||
|
||||
(for version in "${LOCAL_VERSIONS[@]}"; do
|
||||
if [ -z "${action_data[0]}" ] || [[ "$version" =~ ${action_data[0]} ]]; then
|
||||
echo "$version"
|
||||
fi
|
||||
done) | $column
|
||||
;;
|
||||
remote-list)
|
||||
check_environment
|
||||
load_remote_versions
|
||||
|
||||
# shellcheck disable=SC2015
|
||||
[[ -n "$(command -v column)" ]] && { column="column -x"; } || { column="cat"; }
|
||||
|
||||
(for version in "${REMOTE_VERSIONS[@]}"; do
|
||||
if [ -z "${action_data[0]}" ] || [[ "$version" =~ ${action_data[0]} ]]; then
|
||||
echo "$version"
|
||||
fi
|
||||
done) | $column
|
||||
;;
|
||||
install)
|
||||
# only ensure running if the kernel files should be installed
|
||||
[ $do_install -eq 1 ] && guard_run_as_root
|
||||
|
||||
check_environment
|
||||
load_local_versions
|
||||
|
||||
if [ -z "${action_data[0]}" ]; then
|
||||
logn "Finding latest version available on $ppa_host"
|
||||
version=$(latest_remote_version)
|
||||
log
|
||||
|
||||
if [ -z "$version" ]; then
|
||||
err "Could not find latest version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if containsElement "$version" "${LOCAL_VERSIONS[@]}"; then
|
||||
logn "Latest version is $version but seems its already installed"
|
||||
else
|
||||
logn "Latest version is: $version"
|
||||
fi
|
||||
|
||||
if [ $do_install -gt 0 ] && [ $assume_yes -eq 0 ];then
|
||||
logn ", continue? (y/N) "
|
||||
[ $quiet -eq 0 ] && read -rsn1 continue
|
||||
log
|
||||
|
||||
[ "$continue" != "y" ] && [ "$continue" != "Y" ] && { exit 0; }
|
||||
else
|
||||
log
|
||||
fi
|
||||
else
|
||||
load_remote_versions
|
||||
|
||||
version=""
|
||||
if containsElement "v${action_data[0]#v}" "${REMOTE_VERSIONS[@]}"; then
|
||||
version="v"${action_data[0]#v}
|
||||
fi
|
||||
|
||||
[[ -z "$version" ]] && {
|
||||
err "Version '${action_data[0]}' not found"
|
||||
exit 2
|
||||
}
|
||||
shift
|
||||
|
||||
if [ $do_install -gt 0 ] && containsElement "$version" "${LOCAL_VERSIONS[@]}" && [ $assume_yes -eq 0 ]; then
|
||||
logn "It seems version $version is already installed, continue? (y/N) "
|
||||
[ $quiet -eq 0 ] && read -rsn1 continue
|
||||
log
|
||||
|
||||
[ "$continue" != "y" ] && [ "$continue" != "Y" ] && { exit 0; }
|
||||
fi
|
||||
fi
|
||||
|
||||
[ ! -d "$workdir" ] && {
|
||||
mkdir -p "$workdir" 2>/dev/null
|
||||
}
|
||||
[ ! -x "$workdir" ] && {
|
||||
err "$workdir is not writable"
|
||||
exit 1
|
||||
}
|
||||
|
||||
cd "$workdir" || exit 1
|
||||
|
||||
[ $check_signature -eq 1 ] && [ ! -x "$(command -v gpg)" ] && {
|
||||
check_signature=0
|
||||
|
||||
warn "Disable signature check, gpg not available"
|
||||
}
|
||||
|
||||
[[ $sign_kernel -eq 1 && (! -s "$mokKey" || ! -s "$mokCert") ]] && {
|
||||
err "Could not find machine owner key"
|
||||
exit 1
|
||||
}
|
||||
|
||||
IFS=$'\n'
|
||||
|
||||
ppa_uri=$ppa_index${version%\.0}"/"
|
||||
ppa_uri=${ppa_uri/\.0-rc/-rc}
|
||||
|
||||
index=$(download $ppa_host "$ppa_uri")
|
||||
|
||||
if [[ ! $index =~ $build_succeeded_text ]]; then
|
||||
err "Abort, the ${arch} build has not succeeded"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
index=${index%%*<table}
|
||||
|
||||
FILES=()
|
||||
|
||||
found_arch=0
|
||||
uses_subfolders=0
|
||||
section_end="^[[:space:]]*<br>[[:space:]]*$"
|
||||
for line in $index; do
|
||||
if [[ $line =~ $build_succeeded_text ]]; then
|
||||
found_arch=1
|
||||
continue
|
||||
elif [ $found_arch -eq 0 ]; then
|
||||
continue
|
||||
elif [[ $line =~ $section_end ]]; then
|
||||
break
|
||||
fi
|
||||
|
||||
[[ "$line" =~ linux-(image(-(un)?signed)?|headers|modules)-[0-9]+\.[0-9]+\.[0-9]+-[0-9]{6}.*?_(${arch}|all).deb ]] || continue
|
||||
|
||||
[ $use_lowlatency -eq 0 ] && [[ "$line" =~ "-lowlatency" ]] && continue
|
||||
[ $use_lowlatency -eq 1 ] && [[ ! "$line" =~ "-lowlatency" ]] && [[ ! "$line" =~ "_all" ]] && continue
|
||||
[ $use_lpae -eq 0 ] && [[ "$line" =~ "-lpae" ]] && continue
|
||||
[ $use_lpae -eq 1 ] && [[ ! "$line" =~ "-lpae" ]] && [[ ! "$line" =~ "_all" ]] && continue
|
||||
[ $use_snapdragon -eq 0 ] && [[ "$line" =~ "-snapdragon" ]] && continue
|
||||
[ $use_snapdragon -eq 1 ] && [[ ! "$line" =~ "-snapdragon" ]] && [[ ! "$line" =~ "_all" ]] && continue
|
||||
|
||||
line=${line##*href=\"}
|
||||
line=${line%%\">*}
|
||||
|
||||
if [ $uses_subfolders -eq 0 ] && [[ $line =~ ${arch}/linux ]]; then
|
||||
uses_subfolders=1
|
||||
fi
|
||||
|
||||
FILES+=("$line")
|
||||
done
|
||||
unset IFS
|
||||
|
||||
if [ $check_signature -eq 1 ]; then
|
||||
if [ $uses_subfolders -eq 0 ]; then
|
||||
FILES+=("CHECKSUMS" "CHECKSUMS.gpg")
|
||||
else
|
||||
FILES+=("${arch}/CHECKSUMS" "${arch}/CHECKSUMS.gpg")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ${#FILES[@]} -ne $expected_files_count ]; then
|
||||
if [ $assume_yes -eq 0 ]; then
|
||||
logn "Expected to need to download $expected_files_count files but found ${#FILES[@]}, continue? (y/N)"
|
||||
read -rsn1 continue
|
||||
echo ""
|
||||
else
|
||||
continue="y"
|
||||
fi
|
||||
|
||||
[ "$continue" != "y" ] && [ "$continue" != "Y" ] && { exit 0; }
|
||||
fi
|
||||
|
||||
debs=()
|
||||
log "Will download ${#FILES[@]} files from $ppa_host:"
|
||||
for file in "${FILES[@]}"; do
|
||||
workfile=${file##*/}
|
||||
monitor_progress "Downloading $file" "$workdir$workfile"
|
||||
download $ppa_host "$ppa_uri$file" > "$workdir$workfile"
|
||||
|
||||
remove_http_headers "$workdir$workfile"
|
||||
end_monitor_progress
|
||||
|
||||
if [[ "$workfile" =~ \.deb ]]; then
|
||||
debs+=("$workfile")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $check_signature -eq 1 ]; then
|
||||
if ! gpg --list-keys ${ppa_key} >$debug_target 2>&1; then
|
||||
logn "Importing kernel-ppa gpg key "
|
||||
|
||||
if gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv ${ppa_key} >$debug_target 2>&1; then
|
||||
log "ok"
|
||||
else
|
||||
logn "failed"
|
||||
err "Unable to import ppa key"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $check_signature -eq 1 ]; then
|
||||
if gpg --verify CHECKSUMS.gpg CHECKSUMS >$debug_target 2>&1; then
|
||||
log "Signature of checksum file has been successfully verified"
|
||||
else
|
||||
err "Abort, signature of checksum file is NOT OK"
|
||||
exit 4
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $check_checksum -eq 1 ]; then
|
||||
shasums=( "sha256sum" "sha1sum" )
|
||||
|
||||
for shasum in "${shasums[@]}"; do
|
||||
xshasum=$(command -v "$shasum")
|
||||
if [ -n "$xshasum" ] && [ -x "$xshasum" ]; then
|
||||
# shellcheck disable=SC2094
|
||||
shasum_result=$($xshasum --ignore-missing -c CHECKSUMS 2>>$debug_target | tee -a $debug_target | wc -l)
|
||||
|
||||
if [ "$shasum_result" -eq 0 ] || [ "$shasum_result" -ne ${#debs[@]} ]; then
|
||||
err "Abort, $shasum returned an error $shasum_result"
|
||||
exit 4
|
||||
else
|
||||
log "Checksums of deb files have been successfully verified with $shasum"
|
||||
fi
|
||||
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $do_install -eq 1 ]; then
|
||||
if [ ${#debs[@]} -gt 0 ]; then
|
||||
log "Installing ${#debs[@]} packages"
|
||||
$sudo dpkg -i "${debs[@]}" >$debug_target 2>&1
|
||||
else
|
||||
warn "Did not find any .deb files to install"
|
||||
fi
|
||||
else
|
||||
log "deb files have been saved to $workdir"
|
||||
fi
|
||||
|
||||
if [ $sign_kernel -eq 1 ]; then
|
||||
kernelImg=""
|
||||
for deb in "${debs[@]}"; do
|
||||
# match deb file that starts with linux-image-
|
||||
if [[ "$deb" == "linux-image-"* ]]; then
|
||||
imagePkgName="${deb/_*}"
|
||||
|
||||
# The image deb normally only adds one file (the kernal image) to
|
||||
# the /boot folder, find it so we can sign it
|
||||
kernelImg="$(grep /boot/ <<< "$(dpkg -L "$imagePkgName")")"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$kernelImg" ] && [ -x "$(command -v sbsign)" ]; then
|
||||
if $sudo sbverify --cert "$mokCert" "$kernelImg" >/dev/null; then
|
||||
echo "Kernel image $kernelImg is already signed by the provided MOK"
|
||||
elif $sudo sbverify --list "$kernelImg" | grep -v "No signature table present"; then
|
||||
echo "Kernel image $kernelImg is already signed by another MOK"
|
||||
else
|
||||
echo -n "Signing kernel image"
|
||||
$sudo sbsign --key "$mokKey" --cert "$mokCert" --output "$kernelImg" "$kernelImg"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $cleanup_files -eq 1 ]; then
|
||||
log "Cleaning up work folder"
|
||||
rm -f "$workdir"*.deb
|
||||
rm -f "$workdir"CHECKSUM*
|
||||
rmdir "$workdir"
|
||||
fi
|
||||
;;
|
||||
uninstall)
|
||||
guard_run_as_root
|
||||
load_local_versions
|
||||
|
||||
if [ ${#LOCAL_VERSIONS[@]} -eq 0 ]; then
|
||||
echo "No installed mainline kernels found"
|
||||
exit 1
|
||||
elif [ -z "${action_data[0]}" ]; then
|
||||
echo "Which kernel version do you wish to uninstall?"
|
||||
nr=0
|
||||
for version in "${LOCAL_VERSIONS[@]}"; do
|
||||
echo "[$nr]: $version"
|
||||
nr=$((nr + 1))
|
||||
|
||||
[ $nr -gt 9 ] && break
|
||||
done
|
||||
|
||||
echo -n "type the number between []: "
|
||||
read -rn1 index
|
||||
echo ""
|
||||
|
||||
if ! [[ $index == +([0-9]) ]]; then
|
||||
echo "No number entered, exiting"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
uninstall_version=${LOCAL_VERSIONS[$index]}
|
||||
|
||||
if [ -z "$uninstall_version" ]; then
|
||||
echo "Version not found"
|
||||
exit 0
|
||||
fi
|
||||
elif containsElement "v${action_data[0]#v}" "${LOCAL_VERSIONS[@]}"; then
|
||||
uninstall_version="v"${action_data[0]#v}
|
||||
else
|
||||
err "Kernel version ${action_data[0]} not installed locally"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ $assume_yes -eq 0 ]; then
|
||||
echo -n "Are you sure you wish to remove kernel version $uninstall_version? (y/N)"
|
||||
read -rsn1 continue
|
||||
echo ""
|
||||
else
|
||||
continue="y"
|
||||
fi
|
||||
|
||||
if [ "$continue" == "y" ] || [ "$continue" == "Y" ]; then
|
||||
IFS=$'\n'
|
||||
|
||||
pckgs=()
|
||||
for pckg in $(dpkg -l linux-{image,image-[un]?signed,headers,modules}-"${uninstall_version#v}"* 2>$debug_target | cut -d " " -f 3); do
|
||||
# only match kernels from ppa, they have 6 characters as second version string
|
||||
if [[ "$pckg" =~ linux-headers-[0-9]+\.[0-9]+\.[0-9]+-[0-9]{6} ]]; then
|
||||
pckgs+=("$pckg:$arch")
|
||||
pckgs+=("$pckg:all")
|
||||
elif [[ "$pckg" =~ linux-(image(-(un)?signed)?|modules)-[0-9]+\.[0-9]+\.[0-9]+-[0-9]{6} ]]; then
|
||||
pckgs+=("$pckg:$arch")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#pckgs[@]} -eq 0 ]; then
|
||||
warn "Did not find any packages to remove"
|
||||
else
|
||||
echo "The following packages will be removed: "
|
||||
echo "${pckgs[@]}"
|
||||
|
||||
if [ $assume_yes -eq 0 ]; then
|
||||
echo -n "Are you really sure? Do you still have another kernel installed? (y/N)"
|
||||
|
||||
read -rsn1 continue
|
||||
echo ""
|
||||
else
|
||||
continue="y"
|
||||
fi
|
||||
|
||||
if [ "$continue" == "y" ] || [ "$continue" == "Y" ]; then
|
||||
if $sudo env DEBIAN_FRONTEND=noninteractive dpkg --purge "${pckgs[@]}" 2>$debug_target >&2; then
|
||||
log "Kernel $uninstall_version successfully purged"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
Reference in New Issue
Block a user