cmd: Add -s flag to printenv -e for sorted output

Add support for sorting EFI variables by name when using printenv -e.
The -s flag sorts variables alphabetically before display, useful when
dealing with large numbers of variables.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>

Series-to: concept
Series-cc: heinrich
Cover-letter:
efi: Improvements to env print -e
Printing EFI variables can be quite verbose, with many hundreds of lines
of text. Part of this is because GUIDs and hex dumps are included. It
can also be hard to find a few variables visually in an unsorted list.

This series makes the feature more user-friendly:
- Puts verbose output behind a -v flag, so that 'env print -e' behaves
  more like 'env print'
- Adds a -s option to sort the list
END
Series-links: 1:15
This commit is contained in:
Simon Glass
2025-08-21 08:38:46 -06:00
parent ba43199ce9
commit 31bd3547bb
4 changed files with 99 additions and 9 deletions

View File

@@ -1174,7 +1174,7 @@ U_BOOT_LONGHELP(env,
#endif #endif
"env print [-a | name ...] - print environment\n" "env print [-a | name ...] - print environment\n"
#if defined(CONFIG_CMD_NVEDIT_EFI) #if defined(CONFIG_CMD_NVEDIT_EFI)
"env print -e [-guid guid] [-n] [-v] [name ...] print UEFI environment\n" "env print -e [-guid guid] [-n] [-s] [-v] [name ...] print UEFI environment\n"
#endif #endif
#if defined(CONFIG_CMD_RUN) #if defined(CONFIG_CMD_RUN)
"env run var [...] - run commands in an environment variable\n" "env run var [...] - run commands in an environment variable\n"
@@ -1221,10 +1221,11 @@ U_BOOT_CMD_COMPLETE(
"print environment variables", "print environment variables",
"[-a]\n - print [all] values of all environment variables\n" "[-a]\n - print [all] values of all environment variables\n"
#if defined(CONFIG_CMD_NVEDIT_EFI) #if defined(CONFIG_CMD_NVEDIT_EFI)
"printenv -e [-guid guid][-n] [-v] [name ...]\n" "printenv -e [-guid guid][-n] [-s] [-v] [name ...]\n"
" - print UEFI variable 'name' or all the variables\n" " - print UEFI variable 'name' or all the variables\n"
" \"-guid\": GUID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n" " \"-guid\": GUID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n"
" \"-n\": suppress dumping variable's value\n" " \"-n\": suppress dumping variable's value\n"
" \"-s\": sort variables by name\n"
" \"-v\": show GUID, flags, size; also dump (without -n)\n" " \"-v\": show GUID, flags, size; also dump (without -n)\n"
#endif #endif
"printenv name ...\n" "printenv name ...\n"

View File

@@ -15,6 +15,7 @@
#include <malloc.h> #include <malloc.h>
#include <mapmem.h> #include <mapmem.h>
#include <rtc.h> #include <rtc.h>
#include <sort.h>
#include <u-boot/uuid.h> #include <u-boot/uuid.h>
#include <linux/kernel.h> #include <linux/kernel.h>
@@ -142,6 +143,21 @@ out:
return result; return result;
} }
/**
* var_info_cmp() - compare two var_info structures by name
*
* @a: First var_info structure
* @b: Second var_info structure
* Return: comparison result for qsort
*/
static int var_info_cmp(const void *a, const void *b)
{
const struct var_info *va = a;
const struct var_info *vb = b;
return u16_strcmp(va->name, vb->name);
}
/** /**
* efi_dump_var_all() - show information about all the UEFI variables * efi_dump_var_all() - show information about all the UEFI variables
* *
@@ -150,12 +166,14 @@ out:
* @guid_p: GUID to filter by, or NULL for all * @guid_p: GUID to filter by, or NULL for all
* @verbose: if true, show detailed information * @verbose: if true, show detailed information
* @nodump: if true, don't show hexadecimal dump * @nodump: if true, don't show hexadecimal dump
* @sort: if true, sort variables by name before printing
* Return: CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE * Return: CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE
* *
* Show information encoded in all the UEFI variables * Show information encoded in all the UEFI variables
*/ */
static int efi_dump_var_all(int argc, char *const argv[], static int efi_dump_var_all(int argc, char *const argv[],
const efi_guid_t *guid_p, bool verbose, bool nodump) const efi_guid_t *guid_p, bool verbose, bool nodump,
bool sort)
{ {
efi_uintn_t buf_size, size; efi_uintn_t buf_size, size;
struct var_info *var; struct var_info *var;
@@ -209,6 +227,9 @@ static int efi_dump_var_all(int argc, char *const argv[],
goto done; goto done;
} }
if (sort && vars.count > 1)
qsort(vars.data, vars.count, sizeof(struct var_info), var_info_cmp);
alist_for_each(var, &vars) alist_for_each(var, &vars)
efi_dump_single_var(var->name, &var->guid, verbose, nodump); efi_dump_single_var(var->name, &var->guid, verbose, nodump);
@@ -233,10 +254,11 @@ done:
* Return: CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE * Return: CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE
* *
* This function is for "env print -e" or "printenv -e" command: * This function is for "env print -e" or "printenv -e" command:
* => env print -e [-v] [-guid <guid> | -all] [var [...]] * => env print -e [-v] [-s] [-guid <guid> | -all] [var [...]]
* If one or more variable names are specified, show information * If one or more variable names are specified, show information
* named UEFI variables, otherwise show all the UEFI variables. * named UEFI variables, otherwise show all the UEFI variables.
* By default, only variable names are shown. Use -v for verbose output. * By default, only variable names are shown. Use -v for verbose output.
* Use -s to sort variables by name.
*/ */
int do_env_print_efi(struct cmd_tbl *cmdtp, int flag, int argc, int do_env_print_efi(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]) char *const argv[])
@@ -245,6 +267,7 @@ int do_env_print_efi(struct cmd_tbl *cmdtp, int flag, int argc,
efi_guid_t guid; efi_guid_t guid;
bool verbose = false; bool verbose = false;
bool nodump = false; bool nodump = false;
bool sort = false;
efi_status_t ret; efi_status_t ret;
/* Initialize EFI drivers */ /* Initialize EFI drivers */
@@ -270,13 +293,15 @@ int do_env_print_efi(struct cmd_tbl *cmdtp, int flag, int argc,
nodump = true; nodump = true;
} else if (!strcmp(argv[0], "-v")) { } else if (!strcmp(argv[0], "-v")) {
verbose = true; verbose = true;
} else if (!strcmp(argv[0], "-s")) {
sort = true;
} else { } else {
return CMD_RET_USAGE; return CMD_RET_USAGE;
} }
} }
/* enumerate and show all UEFI variables */ /* enumerate and show all UEFI variables */
return efi_dump_var_all(argc, argv, guid_p, verbose, nodump); return efi_dump_var_all(argc, argv, guid_p, verbose, nodump, sort);
} }
/** /**

View File

@@ -25,7 +25,7 @@ Synopsis
env info [-d] [-p] [-q] env info [-d] [-p] [-q]
env load env load
env print [-a | name ...] env print [-a | name ...]
env print -e [-guid guid] [-n] [-v] [name ...] env print -e [-guid guid] [-n] [-s] [-v] [name ...]
env run var [...] env run var [...]
env save env save
env select [target] env select [target]
@@ -233,6 +233,8 @@ in UEFI variables.
with guid format = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx". with guid format = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".
\-n \-n
don't show hexadecimal dump of value for UEFI variables. don't show hexadecimal dump of value for UEFI variables.
\-s
sort UEFI variables by name before displaying.
\-v \-v
show verbose output for UEFI variables including GUID, attributes, data show verbose output for UEFI variables including GUID, attributes, data
size and hexadecimal dump of value. size and hexadecimal dump of value.

View File

@@ -12,7 +12,7 @@ Synopsis
:: ::
printenv [-a] [name ...] printenv [-a] [name ...]
printenv -e [-guid guid][-n][-v] [name] printenv -e [-guid guid][-n][-s][-v] [name]
Description Description
----------- -----------
@@ -32,6 +32,9 @@ The printenv command is used to print environment or UEFI variables.
\-n \-n
don't show hexadecimal dump of value don't show hexadecimal dump of value
\-s
sort variables by name before displaying
\-v \-v
show verbose output including GUID, attributes, data size and hexadecimal show verbose output including GUID, attributes, data size and hexadecimal
dump of value (if not -n) dump of value (if not -n)
@@ -71,7 +74,8 @@ environment variables:
The next example shows the different output modes when displaying UEFI The next example shows the different output modes when displaying UEFI
variables and how to specify a vendor GUID. By default, only the variable variables and how to specify a vendor GUID. By default, only the variable
name is shown. The *-v* flag shows full verbose output, while *-n* shows name is shown. The *-v* flag shows full verbose output, while *-n* shows
details but omits the hexadecimal dump: details but omits the hexadecimal dump. The *-s* flag sorts variables by
name:
:: ::
@@ -86,7 +90,65 @@ details but omits the hexadecimal dump:
8be4df61-93ca-11d2-aa0d-00e098032b8c (EFI_GLOBAL_VARIABLE_GUID) 8be4df61-93ca-11d2-aa0d-00e098032b8c (EFI_GLOBAL_VARIABLE_GUID)
BS|RT|RO, DataSize = 0x6 BS|RT|RO, DataSize = 0x6
00000000: 65 6e 2d 55 53 00 en-US. 00000000: 65 6e 2d 55 53 00 en-US.
=> => print -e -s
525400123456
525400123456
Attempt 1
Attempt 2
Attempt 3
Attempt 4
Attempt 5
Attempt 6
Attempt 7
Attempt 8
Boot0000
Boot0001
Boot0002
Boot0003
BootCurrent
BootOptionSupport
BootOrder
ClientId
ConIn
ConInDev
ConOut
ConOutDev
ErrOut
ErrOutDev
HDDP
InitialAttemptOrder
Key0000
Key0001
Lang
LangCodes
MTC
MemoryTypeInformation
OsIndicationsSupported
PlatformLang
PlatformLangCodes
PlatformRecovery0000
SbatLevel
Timeout
VarErrorFlag
cat
cd..
cd\
copy
debuglasterror
del
dir
lasterror
md
mem
mount
move
nonesting
path
profiles
ren
uefishellsupport
uefishellversion
uefiversion
Configuration Configuration
------------- -------------