sh 根据脚本中定义的规则清除冗余的Ubuntu内核文件,例如要保留的内核数量
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sh 根据脚本中定义的规则清除冗余的Ubuntu内核文件,例如要保留的内核数量相关的知识,希望对你有一定的参考价值。
#!/bin/bash
# What if we could adjust the clock,
# making a day of a virtual AI world much shorter than ours?
# What if a virtual AI being could spend its whole long life
# in a blink of our eyes?
#############################################################
# Purpose:
# Purge redundant Ubuntu kernel files by rules defined in the script
# such as the number of kernels to be preserved
# Compatibility:
# Ubuntu 16, 18; Debian 8, 9 amd64
# And probably some other debian distributions
# Usage:
# 1. Default mode, purge the redundant
# /path/to/purge_kernel_by_rules.bash
# 2. Manual arguments mode, selectively purge.
# It's also affected by default values *KERNELS_TO_PRESERVE.
# 2.1 One argument, no need for other kernel packages such as linux-header-
# /path/to/purge_kernel_by_rules.bash linux-image-333.16.0-6-amd64
# /path/to/purge_kernel_by_rules.bash "linux-image-333.16.0-6-amd64"
# 2.2 Multiple arguments
# ./purge_kernel_by_rules.bash linux-image-333.16.0-6-amd64 linux-image-444.4.0-28-generic
# ./purge_kernel_by_rules.bash "linux-image-444.16.0-20-generic linux-image-444.16.0-20-generic"
# 3. Pipe mode
# 3.1 Simple pipe
# echo linux-image-333.16.0-6-amd64 linux-image-444.4.0-28-generic | ./purge_kernel_by_rules.bash
# 3.2 Pipe mixed with arguments input
# echo linux-image-333.16.0-6-amd64 | ./purge_kernel_by_rules.bash linux-image-444.4.0-28-generic
# The arguments input are listed and purged before the pipe.
# You can also change the number of oldest kernels or newest kernels
# that you'd like to preserve
# by adjusting the values of NUMBER_OF_OLDEST_KERNELS_TO_PRESERVE
# and NUMBER_OF_NEWEST_KERNELS_TO_PRESERVE
# By default 1 oldest and 2 newest along with the ruuning kernel
# are reserved when purge the kernels
# For the running kernel version:
# If it's in the range of oldest/newest kernels
# then the final reserve list will be generated by
# user-defined defalut values
# If it's not in the range of oldest/newest kernels
# then the final reserve list will be generated by
# (user-defined defalut values + running kernel version)
# The number of remaining kernels after purge
# shouldn't be less than the number of total kernels to preserve
#### WARNINGS:
#### This script could seriously damage your system or computer
#### if you use it improperly or carelessly
#### So, use it with cautions and at your own risks
#### A test environment is preferred
# ATTENTION:
# You'd have at least 1 kernel
# for your system to run
# If the numbers here are all 0
# then only the running kernel is reserved
# and all the rest kernels are purged
SET_DEFAULT_VALUES_FOR_RESERVATION(){
NUMBER_OF_OLDEST_KERNELS_TO_PRESERVE=1
NUMBER_OF_NEWEST_KERNELS_TO_PRESERVE=2
number_of_kernels_to_preserve=$((NUMBER_OF_OLDEST_KERNELS_TO_PRESERVE + NUMBER_OF_NEWEST_KERNELS_TO_PRESERVE))
}
print_with_tail_newline(){
printf "$1 \n\n"
}
notice_to_check(){
echo
echo "NOTICE: Check your default values and reset them properly."
print_with_tail_newline "NOTICE: No removing kernels. Exit."
}
check_minimum_values_for_reservation(){
if [ 0 -ge $number_of_kernels_to_preserve ]
then
echo
echo "** CAUTION: The number of non-running kernels to preserve is 0. "
fi
}
handle_default_values_for_reservation(){
SET_DEFAULT_VALUES_FOR_RESERVATION
}
get_running_kernel_info(){
sys_running=`uname -s`
ver_running=`uname -r`
# ver_running="4.4.0-134"
}
list_kernel_candidates(){
print_with_tail_newline "NOTICE: Existing candidate kernel packages on your system:"
dpkg -l | grep ' linux-\(image\|headers\|image-extra\|signed-image\|modules\|modules-extra\)'
print_with_tail_newline "========================================"
issue_info=$(cat /etc/issue)
echo "Currently running:"
echo " $issue_info"
echo "$(echo ' '$sys_running $ver_running)"
}
get_script_args(){
str_list_arg_input_LINUX_IMAGE="$@"
}
generate_OS_LINUX_IMAGE_list(){
# all the linux-image-[ver] pkges on your system
str_list_OS_LINUX_IMAGE=$(dpkg --list | grep linux-image-[0-9] | awk '{ print $2 }' | sort -V | xargs echo)
arr_list_OS_LINUX_IMAGE=($str_list_OS_LINUX_IMAGE)
length_of_arr_list_OS_LINUX_IMAGE=${#arr_list_OS_LINUX_IMAGE[@]}
#print_with_tail_newline $length_of_arr_list_OS_LINUX_IMAGE
#print_with_tail_newline ${arr_list_OS_LINUX_IMAGE[0]}
}
check_OS_LINUX_IMAGE_list_length(){
if [ $length_of_arr_list_OS_LINUX_IMAGE -le $number_of_kernels_to_preserve ]
then
echo "NOTICE: The number of found linux-image kernel versions"
echo "NOTICE: were less or equal to $number_of_kernels_to_preserve ."
notice_to_check
exit 1
fi
}
check_empty_space_input(){
# invalid input like " "
str=$(echo $str_input_list_LINUX_IMAGE)
if [ "y" == "y$str" ]
then
print_with_tail_newline "NOTICE: Invalid empty input::Empty kernel string. Exit."
exit 1
fi
}
check_OS_LINUX_IMAGE_list_length_for_input(){
INPUT_LINUX_IMAGE_list_arr=($str_input_list_LINUX_IMAGE)
INPUT_LINUX_IMAGE_list_arr_length=${#INPUT_LINUX_IMAGE_list_arr[@]}
number_of_kernels_to_remain=$((length_of_arr_list_OS_LINUX_IMAGE - INPUT_LINUX_IMAGE_list_arr_length))
if [ $number_of_kernels_to_preserve -gt $number_of_kernels_to_remain ]
then
echo "NOTICE: The number of remaining versions of linux-image kernel"
echo "NOTICE: should be GREATER than $number_of_kernels_to_preserve"
echo "NOTICE: after purging the input."
notice_to_check
exit 1
fi
}
get_running_image_str(){
for image_str in ${arr_list_OS_LINUX_IMAGE[@]}
do
result=$(printf "$image_str" | grep -n "$ver_running")
if [ 0 -eq $? ]
then
# remove the leading "num:" part in the result
image_str_running="${result#*:}"
break
fi
done
#echo "arr_list_OS_LINUX_IMAGE: ${arr_list_OS_LINUX_IMAGE[@]}"
#echo "image_str_running: $image_str_running"
}
make_raw_reserve_list(){
# make list for the oldest kernels to reserve
arr_reserve_list_oldest_LINUX_IMAGE=(${arr_list_OS_LINUX_IMAGE[@]:0:$NUMBER_OF_OLDEST_KERNELS_TO_PRESERVE})
str_reserve_list_oldest_LINUX_IMAGE="${arr_reserve_list_oldest_LINUX_IMAGE[@]}"
# make list for the newest kernels to reserve
length=${#arr_list_OS_LINUX_IMAGE[@]}
start_idx_arr_reserve_list_newest_LINUX_IMAGE=$(($length - $NUMBER_OF_NEWEST_KERNELS_TO_PRESERVE))
arr_reserve_list_newest_LINUX_IMAGE=(${arr_list_OS_LINUX_IMAGE[@]:$start_idx_arr_reserve_list_newest_LINUX_IMAGE})
str_reserve_list_newest_LINUX_IMAGE="${arr_reserve_list_newest_LINUX_IMAGE[@]}"
reserve_list_raw="$str_reserve_list_oldest_LINUX_IMAGE $str_reserve_list_newest_LINUX_IMAGE"
}
make_reserve_list(){
# add the running kernel version to the raw_reserve_list #
check_minimum_values_for_reservation
get_running_image_str
make_raw_reserve_list
printf "$reserve_list_raw" | grep -q "$image_str_running"
if [ 0 -ne $? ]
then
reserve_list="$image_str_running $reserve_list_raw"
else
reserve_list="$reserve_list_raw"
fi
print_with_tail_newline "Reserved kernel list: $reserve_list"
}
do_input(){
# arg input, pipe input or pipe with arg input
str_input_list_LINUX_IMAGE=$1
check_empty_space_input
check_OS_LINUX_IMAGE_list_length_for_input
arr_raw_purge_list_LINUX_IMAGE=($str_input_list_LINUX_IMAGE)
make_reserve_list
}
make_reserve_list_for_default(){
# only show reserve list for terminal users
# not really used by the default mode
make_reserve_list
# This is the real reserve_list used by the default mode
get_running_image_str
reserve_list="$image_str_running"
}
do_default(){
echo "NOTICE: Purge with default mode."
kernel_purge_list_length=$(($length_of_arr_list_OS_LINUX_IMAGE - $number_of_kernels_to_preserve))
arr_raw_purge_list_LINUX_IMAGE=(${arr_list_OS_LINUX_IMAGE[@]:$NUMBER_OF_OLDEST_KERNELS_TO_PRESERVE:$kernel_purge_list_length})
arr_raw_purge_list_LINUX_IMAGE_length=${#arr_raw_purge_list_LINUX_IMAGE[@]}
make_reserve_list_for_default
}
do_nopipe(){
# manual argument mode, purge from user arguments input
if [ -n "$str_list_arg_input_LINUX_IMAGE" ]
then
echo "NOTICE: Purge with user arguments input mode."
do_input "$str_list_arg_input_LINUX_IMAGE"
fi
# default mode, no user-input arg
if [ -z "$str_list_arg_input_LINUX_IMAGE" ]
then
do_default
fi
}
do_pipe(){
echo "NOTICE: Purge with user pipe (or pipe-mixed) input mode."
# cat from default stdin, which receive data from the pipe
str_pipe_lines_LINUX_IMAGE=$(cat | tr -s '\n' ' ')
str_list_pipe_input_LINUX_IMAGE="$str_list_arg_input_LINUX_IMAGE $str_pipe_lines_LINUX_IMAGE"
do_input "$str_list_pipe_input_LINUX_IMAGE"
}
how_to_do(){
generate_OS_LINUX_IMAGE_list
check_OS_LINUX_IMAGE_list_length
# check pipe status
if [ -t 0 ]
then
do_nopipe
else
do_pipe
fi
}
init_purge_list_strs(){
# 1 package for ubuntu and debian 8 amd64
str_purge_list_LINUX_IMAGE=""
# 3 packages for ubuntu 16
str_purge_list_LINUX_HEADERS=""
str_purge_list_LINUX_IMAGE_EXTRA=""
str_purge_list_LINUX_SIGNED_IMAGE=""
# 2 packages for ubuntu 18
str_purge_list_LINUX_MODULES=""
str_purge_list_LINUX_MODULES_EXTRA=""
# all packages for both ubuntu and debian
kernel_purge_list_str=""
}
get_version_numbers_by_image_string(){
image_ver=$(echo $image_string | cut -d - -f 3-4)
ver_n1=${image_ver%%.*}
ver_n1_n2=${image_ver%.*}
ver_n2=${ver_n1_n2#*.}
}
get_ubuntu_unique_kernels(){
# change header kernel format from debian to ubuntu
arr_purge_list_LINUX_HEADERS[$j]=${debian_header//-common}
get_version_numbers_by_image_string
# ubuntu 18, kernel 4.15.0
if [[ ("$ver_n1" -eq 4 && "$ver_n2" -ge 15) || "$ver_n1" -ge 5 ]]
then
arr_purge_list_LINUX_MODULES[$j]="${image_string/image/modules}"
arr_purge_list_LINUX_MODULES_EXTRA[$j]="${image_string/image/modules-extra}"
else
arr_purge_list_LINUX_IMAGE_EXTRA[$j]="${image_string//image/image-extra}"
arr_purge_list_LINUX_SIGNED_IMAGE[$j]="${image_string//image/signed-image}"
fi
}
get_linux_distribution_unique_kernels(){
provider_id=${issue_info%% *}
#for test
#provider_id="Debian"
length=${#arr_raw_purge_list_LINUX_IMAGE[@]}
j=0
for ((i=0;$i<$length;i++))
do
# skip if the kernel string is in the reserved kernel version list
image_string="${arr_raw_purge_list_LINUX_IMAGE[$i]}"
printf "$reserve_list" | grep -q "$image_string"
if [ 0 -eq $? ]
then
continue
fi
#echo "j: $j"
# header for debian
debian_header="${image_string//image/headers}"
arr_purge_list_LINUX_HEADERS[$j]="$debian_header"
# image for debian, ubuntu
arr_purge_list_LINUX_IMAGE[$j]="$image_string"
# ubuntu 16, 18
if [ "Ubuntu" == "$provider_id" ]
then
get_ubuntu_unique_kernels
fi
j=$((j+1))
done
}
format_str_kernel_purge_list(){
# change *_purge_list arr to str here
kernel_purge_list_str=" \
$str_purge_list_LINUX_IMAGE \
$str_purge_list_LINUX_HEADERS \
$str_purge_list_LINUX_IMAGE_EXTRA \
$str_purge_list_LINUX_SIGNED_IMAGE \
$str_purge_list_LINUX_MODULES \
$str_purge_list_LINUX_MODULES_EXTRA"
}
print_if_no_empty_line(){
str_purge_list_no_side_spaces="$(echo $1)"
if [ y"" != y"$str_purge_list_no_side_spaces" ]
then
echo "$str_purge_list_no_side_spaces"
fi
}
print_kernel_purge_list(){
print_if_no_empty_line "$str_purge_list_LINUX_IMAGE"
print_if_no_empty_line "$str_purge_list_LINUX_HEADERS"
echo
print_if_no_empty_line "$str_purge_list_LINUX_IMAGE_EXTRA"
print_if_no_empty_line "$str_purge_list_LINUX_SIGNED_IMAGE"
echo
print_if_no_empty_line "$str_purge_list_LINUX_MODULES"
print_if_no_empty_line "$str_purge_list_LINUX_MODULES_EXTRA"
echo
}
generate_kernel_purge_list_str(){
print_with_tail_newline "NOTICE: Generated lists of all kernel packages to be purged:"
init_purge_list_strs
get_linux_distribution_unique_kernels
str_purge_list_LINUX_HEADERS="${arr_purge_list_LINUX_HEADERS[@]}"
str_purge_list_LINUX_IMAGE="${arr_purge_list_LINUX_IMAGE[@]}"
str_purge_list_LINUX_IMAGE_EXTRA="${arr_purge_list_LINUX_IMAGE_EXTRA[@]}"
str_purge_list_LINUX_SIGNED_IMAGE="${arr_purge_list_LINUX_SIGNED_IMAGE[@]}"
str_purge_list_LINUX_MODULES="${arr_purge_list_LINUX_MODULES[@]}"
str_purge_list_LINUX_MODULES_EXTRA="${arr_purge_list_LINUX_MODULES_EXTRA[@]}"
print_kernel_purge_list
format_str_kernel_purge_list
}
vital_check(){
while true
do
echo "NOTICE: Check all the kernel versions above before the next step."
read -p "Press Ctrl+C to interrupt or press Enter to continue: " input
if [ -z "$input" ]
then
break
fi
done
print_with_tail_newline "Continued.. "
}
purge_kernels_by_purge_list_str(){
purge_cmd="apt-get purge $kernel_purge_list_str"
print_with_tail_newline "$purge_cmd"
# grep command in this script could return err
# so set this in the later part of the script
set -e
$purge_cmd
update-grub2
}
main(){
handle_default_values_for_reservation
get_running_kernel_info
list_kernel_candidates
get_script_args "$@"
how_to_do
generate_kernel_purge_list_str
vital_check
purge_kernels_by_purge_list_str
}
##################################
main "$@"
以上是关于sh 根据脚本中定义的规则清除冗余的Ubuntu内核文件,例如要保留的内核数量的主要内容,如果未能解决你的问题,请参考以下文章