From 7f3910390b1b7720fe54307bec0656ec9e21e21c Mon Sep 17 00:00:00 2001 From: Matthias Kruk Date: Sat, 9 Jul 2022 11:50:06 +0900 Subject: [PATCH] toolbox.sh: Make command-not-found errors more helpful Command-not-found errors often occur because the user forgot to include a module. In such cases, it would be helpful if the default error message included suggestions for modules to include. This commit adds a `command_not_found_handle()` function that overrides bash's default behavior: aside of the usual error message, this function will print all module names that the missing function may be part of (as determined by its name) to stderr. --- toolbox.sh | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/toolbox.sh b/toolbox.sh index f690b01..b267299 100644 --- a/toolbox.sh +++ b/toolbox.sh @@ -1,7 +1,7 @@ #!/bin/bash # toolbox.sh - Framework for modular bash scripts -# Copyright (C) 2021 Matthias Kruk +# Copyright (C) 2021-2022 Matthias Kruk # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -36,6 +36,7 @@ __toolbox_init() { readonly -f have readonly -f _try_include readonly -f include + readonly -f command_not_found_handle return 0 } @@ -108,6 +109,40 @@ include() { return 0 } +command_not_found_handle() { + local command="$1" + # local args=("${@:2}") # not used + + local searchpath + declare -A candidates + + # Display the same message that bash usually would + echo "bash: $command: command not found" 1>&2 + + for searchpath in "${__TOOLBOX_MODULEPATH[@]}"; do + local module + + while read -r module; do + local module_name + local prefix + + module_name="${module#"$searchpath"/}" + module_name="${module_name%.sh}" + prefix="${module_name//\//_}" + + if [[ "$command" == "$prefix"* ]]; then + candidates["$module_name"]="$module" + fi + done < <(find -L "$searchpath" -type f -iname "*.sh") + done + + if (( ${#candidates[@]} > 0 )); then + echo "Did you forget to include a module? Possible candidates are: ${!candidates[*]}" 1>&2 + fi + + return 127 +} + { if ! compgen -v | grep "^__TOOLBOX_INCLUDED$" &> /dev/null; then if ! __toolbox_init; then -- 2.47.3