diff --git a/41_snapshots-btrfs b/41_snapshots-btrfs index 0dddfec..05736c3 100755 --- a/41_snapshots-btrfs +++ b/41_snapshots-btrfs @@ -1,4 +1,4 @@ -#! /usr/bin/env bash +#! /usr/bin/env sh # # Written by: Antynea # BTC donation address: 1Lbvz244WA8xbpHek9W2Y12cakM6rDe5Rt @@ -41,14 +41,16 @@ set -e sysconfdir="/etc" grub_btrfs_config="${sysconfdir}/default/grub-btrfs/config" +# shellcheck disable=SC1090 [ -f "$grub_btrfs_config" ] && . "$grub_btrfs_config" +# shellcheck disable=SC1091 [ -f "${sysconfdir}/default/grub" ] && . "${sysconfdir}/default/grub" ## Error Handling print_error() { - local err_msg="$*" - local bug_report="If you think an error has occurred, please file a bug report at \"https://github.com/Antynea/grub-btrfs\"" + err_msg="$*" + bug_report="If you think an error has occurred, please file a bug report at \"https://github.com/Antynea/grub-btrfs\"" printf "%s\n" "${err_msg}" "${bug_report}" >&2 ; exit 0 } @@ -77,8 +79,10 @@ done ## Exit the script, if: [ "$(echo "$GRUB_BTRFS_DISABLE" | tr '[:upper:]' '[:lower:]')" = 'true' ] && print_error "GRUB_BTRFS_DISABLE is set to true (default=false)" if ! type btrfs >/dev/null 2>&1; then print_error "btrfs-progs isn't installed"; fi +# shellcheck disable=SC1090,SC2015 [ -f "${GRUB_BTRFS_MKCONFIG_LIB:-/usr/share/grub/grub-mkconfig_lib}" ] && . "${GRUB_BTRFS_MKCONFIG_LIB:-/usr/share/grub/grub-mkconfig_lib}" || print_error "grub-mkconfig_lib couldn't be found" -[[ "$(btrfs filesystem df / 2>&1)" == *"not a btrfs filesystem"* ]] && print_error "Root filesystem isn't btrfs" +# shellcheck disable=SC2005 +if echo "$(btrfs filesystem df / 2>&1)" | grep "not a btrfs filesystem" >/dev/null 2>&1; then print_error "Root filesystem isn't btrfs"; fi printf "Detecting snapshots ...\n" >&2 ; @@ -110,16 +114,28 @@ fi ## Probe information of Root and Boot devices # Probe info "Root partition" +# shellcheck disable=SC2154 # grub_probe is provided by grub environment root_device=$(${grub_probe} --target=device /) # Root device +# shellcheck disable=SC2086 # we actually need word splitting here if we have several root devices (e.g. RAID) root_uuid=$(${grub_probe} --device ${root_device} --target="fs_uuid" 2>/dev/null) # UUID of the root device root_uuid_subvolume=$(btrfs subvolume show / 2>/dev/null) || print_error "UUID of the root subvolume is not available"; # If UUID of root subvolume is not available, then exit -root_uuid_subvolume=$(awk -F":" 'match($1, /(^[ \t]+UUID)/) {sub(/^[ \t]+/, "", $2); print $2}' <<< "$root_uuid_subvolume") # UUID of the root subvolume ' +root_uuid_subvolume=$(awk -F":" 'match($1, /(^[ \t]+UUID)/) {sub(/^[ \t]+/, "", $2); print $2}' </dev/null) # UUID of the boot device boot_uuid_subvolume=$(btrfs subvolume show "$boot_directory" 2>/dev/null) || boot_uuid_subvolume=" UUID: $root_uuid_subvolume"; # If boot folder isn't a subvolume, then UUID=root_uuid_subvolume -boot_uuid_subvolume=$(awk -F":" 'match($1, /(^[ \t]+UUID)/) {sub(/^[ \t]+/, "", $2); print $2}' <<< "$boot_uuid_subvolume") # UUID of the boot subvolume ' +boot_uuid_subvolume=$(awk -F":" 'match($1, /(^[ \t]+UUID)/) {sub(/^[ \t]+/, "", $2); print $2}' </dev/null) # hints string +# shellcheck disable=SC2086 # we actually need word splitting here if we have several devices boot_fs=$(${grub_probe} --device ${boot_device} --target="fs" 2>/dev/null) # Type filesystem of boot device ## Parameters passed to the kernel @@ -143,7 +159,7 @@ fi ## Detect rootflags detect_rootflags() { - local fstabflags=$(grep -oE '^\s*[^#][[:graph:]]+\s+/\s+btrfs\s+[[:graph:]]+' "${grub_btrfs_mount_point}/${snap_dir_name_trim}/etc/fstab" \ + fstabflags=$(grep -oE '^\s*[^#][[:graph:]]+\s+/\s+btrfs\s+[[:graph:]]+' "${grub_btrfs_mount_point}/${snap_dir_name_trim}/etc/fstab" \ | sed -E 's/^.*[[:space:]]([[:graph:]]+)$/\1/;s/,?subvol(id)?=[^,$]+//g;s/^,//') rootflags="rootflags=${fstabflags:+$fstabflags,}${GRUB_BTRFS_ROOTFLAGS:+$GRUB_BTRFS_ROOTFLAGS,}" } @@ -151,8 +167,8 @@ detect_rootflags() unmount_grub_btrfs_mount_point() { if [ -d "$grub_btrfs_mount_point" ]; then - local wait=true - local wait_max=0 + wait=true + wait_max=0 printf "Unmount %s .." "$grub_btrfs_mount_point" >&2; while $wait; do if grep -qs "$grub_btrfs_mount_point" /proc/mounts; then @@ -200,6 +216,7 @@ make_menu_entries() # prefix_i=${i%%"-"*} suffix_i=${i#*"-"} # alt_suffix_i=${i##*"-"} + # shellcheck disable=SC2269 # this is a way to exit the if..elif.. if [ "${kversion}" = "${suffix_i}" ]; then i="${i}"; elif [ "${kversion}.img" = "${suffix_i}" ]; then i="${i}"; elif [ "${kversion}-fallback.img" = "${suffix_i}" ]; then i="${i}"; @@ -279,21 +296,21 @@ make_menu_entries() ## Trim a string from leading and trailing whitespaces trim() { - local var="$*" + var="$*" var="${var#"${var%%[![:space:]]*}"}" var="${var%"${var##*[![:space:]]}"}" - echo -n "$var" + printf '%s' "$var" } ## List of snapshots on filesystem snapshot_list() { - local snapper_info="info.xml" - local timeshift_info="info.json" - local date_snapshots=() - local path_snapshots=() - local type_snapshots=() - local description_snapshots=() + snapper_info="info.xml" + timeshift_info="info.json" + date_snapshots=() + path_snapshots=() + type_snapshots=() + description_snapshots=() IFS=$'\n' for snap in $(btrfs subvolume list -sa "${btrfs_subvolume_sort}" /); do # Parse btrfs snapshots IFS=$oldIFS @@ -320,7 +337,8 @@ snapshot_list() local description_snapshot="N/A" # path to yabsnap snapshot meta data - local yabsnap_info="$grub_btrfs_mount_point/${path_snapshot%"/"*}/$(echo "${snap[13]}" | awk -F'/' '{print $3 "-meta.json"}')" + local yabsnap_info + yabsnap_info="$grub_btrfs_mount_point/${path_snapshot%"/"*}/$(echo "${snap[13]}" | awk -F'/' '{print $3 "-meta.json"}')" if [[ -s "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$snapper_info" ]] ; then type_snapshot=$(awk -F"<|>" 'match($2, /^type/) {print $3}' "$grub_btrfs_mount_point/${path_snapshot%"/"*}/$snapper_info") # search matching string beginning "type" @@ -399,30 +417,31 @@ parse_snapshot_list() snap_dir_name="$(echo "$item" | cut -d'|' -f2)" # column_2 snap_dir_name_trim="$(trim "$snap_dir_name")" - snap_snapshot="$snap_dir_name" # Used by "title_format" function - + # shellcheck disable=SC2034 # Used by "title_format" function + snap_snapshot="$snap_dir_name" + # shellcheck disable=SC2034 # Used by "title_format" function snap_type="$(echo "$item" | cut -d'|' -f3)" # column_3 - + # shellcheck disable=SC2034 # Used by "title_format" function snap_description="$(echo "$item" | cut -d'|' -f4)" # column_4 } ## Detect kernels in "boot_directory" detect_kernel() { - list_kernel=() + list_kernel="" # Original kernel (auto-detect) for okernel in "${boot_dir}"/vmlinuz-* \ "${boot_dir}"/vmlinux-* \ "${boot_dir}"/kernel-* ; do [ ! -f "${okernel}" ] && continue; - list_kernel+=("$okernel") + list_kernel="${list_kernel} $okernel" done # Custom name kernel in "GRUB_BTRFS_NKERNEL" if [ -n "${GRUB_BTRFS_NKERNEL}" ] ; then - for ckernel in "${boot_dir}/${GRUB_BTRFS_NKERNEL[@]}" ; do + for ckernel in "${boot_dir}"/${GRUB_BTRFS_NKERNEL} ; do [ ! -f "${ckernel}" ] && continue; - list_kernel+=("$ckernel") + list_kernel="${list_kernel} $okernel" done fi } @@ -468,7 +487,7 @@ detect_microcode() # Custom name microcode in "GRUB_BTRFS_CUSTOM_MICROCODE" if [ -n "${GRUB_BTRFS_CUSTOM_MICROCODE}" ] ; then for cucode in "${boot_dir}/${GRUB_BTRFS_CUSTOM_MICROCODE[@]}" ; do - [[ ! -f "${cucode}" ]] && continue + [ ! -f "${cucode}" ] && continue list_ucode+=("$cucode") done fi @@ -481,7 +500,7 @@ title_format() { title_menu="|" # "|" is for visuals only title_submenu="|" # "|" is for visuals only - [[ -z "${GRUB_BTRFS_TITLE_FORMAT}" ]] && GRUB_BTRFS_TITLE_FORMAT=("date" "snapshot" "type" "description"); # Default parameters + [ -z "${GRUB_BTRFS_TITLE_FORMAT}" ] && GRUB_BTRFS_TITLE_FORMAT=("date" "snapshot" "type" "description"); # Default parameters for key in "${!GRUB_BTRFS_TITLE_FORMAT[@]}"; do [[ ${GRUB_BTRFS_TITLE_FORMAT[$key],,} != "${title_column[${GRUB_BTRFS_TITLE_FORMAT[$key]}],,}" ]] && continue; # User used wrong parameter declare -n var="snap_${GRUB_BTRFS_TITLE_FORMAT[$key],,}" # $var is a indirect variable @@ -496,15 +515,15 @@ title_format() # Adds a header to the grub-btrfs.cfg file header_menu() { - local header_entry="" - [[ -z "${GRUB_BTRFS_TITLE_FORMAT}" ]] && GRUB_BTRFS_TITLE_FORMAT=("date" "snapshot" "type" "description"); # Default parameters + header_entry="" + [ -z "${GRUB_BTRFS_TITLE_FORMAT}" ] && GRUB_BTRFS_TITLE_FORMAT=("date" "snapshot" "type" "description"); # Default parameters for key in "${!GRUB_BTRFS_TITLE_FORMAT[@]}"; do [[ ${GRUB_BTRFS_TITLE_FORMAT[$key],,} != "${title_column[${GRUB_BTRFS_TITLE_FORMAT[$key]}],,}" ]] && continue; # User used wrong parameter declare -n var="snap_${GRUB_BTRFS_TITLE_FORMAT[$key],,}" # $var is a indirect variable # Center alignment, needed for pretty formatting local lenght_title_column_left=$((${#var}-${#title_column[${GRUB_BTRFS_TITLE_FORMAT[$key],,}]})) ((lenght_title_column_left%2)) && lenght_title_column_left=$((lenght_title_column_left+1)); # If the difference is an odd number, add an extra space - lenght_title_column_left=$((((lenght_title_column_left/2)+${#title_column[${GRUB_BTRFS_TITLE_FORMAT[$key],,}]}))); + lenght_title_column_left=$(((lenght_title_column_left/2)+${#title_column[${GRUB_BTRFS_TITLE_FORMAT[$key],,}]})); local lenght_title_column_right=$(((${#var}-lenght_title_column_left)+1)) #+1 is necessary for extra "|" character header_entry+=$(printf "%${lenght_title_column_left}s%${lenght_title_column_right}s" "${title_column[${GRUB_BTRFS_TITLE_FORMAT[$key],,}]}" "|") # Final "|" is for visuals only done @@ -523,6 +542,7 @@ boot_bounded() boot_dir="$grub_btrfs_mount_point/$snap_dir_name_trim$boot_directory" detect_kernel if [ -z "${list_kernel}" ]; then continue; fi + # TODO name_kernel=("${list_kernel[@]##*"/"}") detect_initramfs name_initramfs=("${list_initramfs[@]##*"/"}") @@ -614,6 +634,7 @@ if [ "${count_limit_snap}" = "0" ] || [ -z "${count_limit_snap}" ]; then fi # Move "grub-btrfs.new" to "grub-btrfs.cfg" header_menu +# shellcheck disable=SC2154 # bindir is provided by grub environment if "${bindir}/${GRUB_BTRFS_SCRIPT_CHECK:-grub-script-check}" "$grub_btrfs_directory/grub-btrfs.new"; then cat "$grub_btrfs_directory/grub-btrfs.new" > "$grub_btrfs_directory/grub-btrfs.cfg" rm -f "$grub_btrfs_directory/grub-btrfs.new" "$grub_btrfs_directory/grub-btrfs.cfg.bkp" diff --git a/config b/config index 03f8f4e..2435406 100644 --- a/config +++ b/config @@ -1,7 +1,7 @@ #!/usr/bin/env bash -GRUB_BTRFS_VERSION=4.13-yabsnap_info_support-2024-03-06T13:43:57+00:00 +GRUB_BTRFS_VERSION=4.13-fix-bashisms-2024-03-27T20:48:48+00:00 # Disable grub-btrfs. # Default: "false"