Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix bashisms #326

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 51 additions & 30 deletions 41_snapshots-btrfs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#! /usr/bin/env bash
#! /usr/bin/env sh
#
# Written by: Antynea
# BTC donation address: 1Lbvz244WA8xbpHek9W2Y12cakM6rDe5Rt
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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 ;

Expand Down Expand Up @@ -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}' <<EOF
"$root_uuid_subvolume"
EOF
) # UUID of the root subvolume '
# Probe info "Boot partition"
# shellcheck disable=SC2086 # we actually need word splitting here if we have several devices
boot_device=$(${grub_probe} --target=device ${boot_directory}) # Boot device
# shellcheck disable=SC2086 # we actually need word splitting here if we have several devices
boot_uuid=$(${grub_probe} --device ${boot_device} --target="fs_uuid" 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}' <<EOF
"$boot_uuid_subvolume"
EOF
) # UUID of the boot subvolume '
# shellcheck disable=SC2086 # we actually need word splitting here if we have several devices
boot_hs=$(${grub_probe} --device ${boot_device} --target="hints_string" 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
Expand All @@ -143,16 +159,16 @@ 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,}"
}

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
Expand Down Expand Up @@ -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}";
Expand Down Expand Up @@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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[@]##*"/"}")
Expand Down Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion config
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
Loading