From: Ahmad Fatoum <[email protected]> We currently have no way to differentiate between a variable that's set and one that's empty, but this would be useful for scripts that source other scripts for customization and want to verify if some variables have been explicitly set to be empty or not, e.g. an initrd override that's empty would mean to omit the initrd as opposed to not setting it, which means to attempt no override.
Signed-off-by: Ahmad Fatoum <[email protected]> --- commands/test.c | 12 +++++++++++- test/py/test_shell.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/commands/test.c b/commands/test.c index c2f2993df406..d32536b0fd3e 100644 --- a/commands/test.c +++ b/commands/test.c @@ -10,6 +10,7 @@ #include <common.h> #include <command.h> #include <fnmatch.h> +#include <environment.h> #include <fs.h> #include <linux/stat.h> @@ -34,6 +35,7 @@ typedef enum { OPT_CHAR, OPT_SYMBOLIC_LINK, OPT_NONZERO_SIZE, + OPT_VAR_EXISTS, OPT_MAX, } test_opts; @@ -58,6 +60,7 @@ static char *test_options[] = { [OPT_CHAR] = "-c", [OPT_SYMBOLIC_LINK] = "-L", [OPT_NONZERO_SIZE] = "-s", + [OPT_VAR_EXISTS] = "-v", }; static int parse_opt(const char *opt) @@ -197,6 +200,13 @@ static int do_test(int argc, char *argv[]) expr = (opt == OPT_ZERO) ? zero : !zero; break; + case OPT_VAR_EXISTS: + adv = 2; + if (left < 2) + break; + expr = getenv(ap[1]) != NULL; + break; + case OPT_FILE: case OPT_DIRECTORY: case OPT_EXISTS: @@ -302,7 +312,7 @@ static const char * const test_aliases[] = { "[", "[[", NULL}; BAREBOX_CMD_HELP_START(test) BAREBOX_CMD_HELP_TEXT("Options:") BAREBOX_CMD_HELP_TEXT("\t!, =, !=, -eq, -ne, -ge, -gt, -le, -lt, -o, -a, -z, -n, -d, -e,") -BAREBOX_CMD_HELP_TEXT("\t-s, -f, -L; see 'man test' on your PC for more information.") +BAREBOX_CMD_HELP_TEXT("\t-s, -f, -L, -v; see 'man test' on your PC for more information.") BAREBOX_CMD_HELP_END BAREBOX_CMD_START(test) diff --git a/test/py/test_shell.py b/test/py/test_shell.py index 22a076d10e1e..23c2d5dbb0b6 100644 --- a/test/py/test_shell.py +++ b/test/py/test_shell.py @@ -112,3 +112,46 @@ def test_cmd_clk(barebox, barebox_config): assert regions >= 0 assert count_dicts_in_command_output(barebox, 'clk_dump -vj') == regions + + +def test_barebox_test_var_exists(barebox, barebox_config): + skip_disabled(barebox_config, "CONFIG_CMD_TEST", "CONFIG_CMD_ECHO") + + # Create a file with variable definitions + barebox.run_check('echo -o /tmp/testvars "TEST_VAR=value"') + barebox.run_check('echo -a /tmp/testvars "EMPTY_VAR="') + + # Test with unset variable - should fail + _, _, returncode = barebox.run('test -v NONEXISTENT_VAR') + assert returncode == 1 + + _, _, returncode = barebox.run('[[ -v NONEXISTENT_VAR ]]') + assert returncode == 1 + + # Test with set variable - should succeed + _, _, returncode = barebox.run('. /tmp/testvars; test -v TEST_VAR') + assert returncode == 0 + + _, _, returncode = barebox.run('. /tmp/testvars; [[ -v TEST_VAR ]]') + assert returncode == 0 + + # Test with empty but set variable - should succeed + _, _, returncode = barebox.run('. /tmp/testvars; test -v EMPTY_VAR') + assert returncode == 0 + + _, _, returncode = barebox.run('. /tmp/testvars; [[ -v EMPTY_VAR ]]') + assert returncode == 0 + + # Test negation with ! + _, _, returncode = barebox.run('test ! -v NONEXISTENT_VAR') + assert returncode == 0 + + _, _, returncode = barebox.run('. /tmp/testvars; test ! -v TEST_VAR') + assert returncode == 1 + + # Test in conditional context + barebox.run_check('. /tmp/testvars; [[ -v TEST_VAR ]] && echo ok') + barebox.run_check('[[ ! -v NONEXISTENT_VAR ]] && echo ok') + + # Clean up + barebox.run_check('rm /tmp/testvars') -- 2.47.3
