[PATCH 3/3] cmd: test: fix handling of single-argument form of test

Rasmus Villemoes ravi at prevas.dk
Wed Mar 11 13:09:10 CET 2026


POSIX states that

  0 arguments:
      Exit false (1).
  1 argument:
      Exit true (0) if $1 is not null; otherwise, exit false.

and at least bash and busybox sh behave that way.

The current 'argc < 3' does the right thing for a non-existing or
empty argv[1], but not for a non-empty argv[1]. Fix that and add
corresponding test cases.

Signed-off-by: Rasmus Villemoes <ravi at prevas.dk>
---
 cmd/test.c     | 11 +++++++++--
 test/hush/if.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/cmd/test.c b/cmd/test.c
index f0645ef98f1..0d0f090386c 100644
--- a/cmd/test.c
+++ b/cmd/test.c
@@ -71,10 +71,17 @@ static int do_test(struct cmd_tbl *cmdtp, int flag, int argc,
 		argc--;
 	}
 
-	/* args? */
-	if (argc < 3)
+	/*
+	 * Per POSIX, 'test' with 0 arguments should return 1, while
+	 * 'test <arg>' should be equivalent to 'test -n <arg>',
+	 * i.e. true if and only if <arg> is not empty.
+	 */
+	if (argc < 2)
 		return 1;
 
+	if (argc == 2)
+		return !strcmp(argv[1], "");
+
 #ifdef DEBUG
 	{
 		debug("test(%d):", argc);
diff --git a/test/hush/if.c b/test/hush/if.c
index 148e9a53e90..e82a95aaf27 100644
--- a/test/hush/if.c
+++ b/test/hush/if.c
@@ -32,6 +32,15 @@ static int hush_test_if_base(struct unit_test_state *uts)
 	sprintf(if_formatted, if_format, "false");
 	ut_asserteq(1, run_command(if_formatted, 0));
 
+	sprintf(if_formatted, if_format, "test");
+	ut_asserteq(1, run_command(if_formatted, 0));
+
+	sprintf(if_formatted, if_format, "test ''");
+	ut_asserteq(1, run_command(if_formatted, 0));
+
+	sprintf(if_formatted, if_format, "test 'abc'");
+	ut_assertok(run_command(if_formatted, 0));
+
 	return 0;
 }
 HUSH_TEST(hush_test_if_base, 0);
@@ -343,6 +352,27 @@ static int hush_test_lbracket_alias(struct unit_test_state *uts)
 	ut_asserteq(1, run_command(if_formatted, 0));
 	ut_assert_nextline(missing_rbracket_error);
 
+	sprintf(if_formatted, if_format, "[ ]");
+	ut_asserteq(1, run_command(if_formatted, 0));
+
+	sprintf(if_formatted, if_format, "[");
+	ut_asserteq(1, run_command(if_formatted, 0));
+	ut_assert_nextline(missing_rbracket_error);
+
+	sprintf(if_formatted, if_format, "[ '' ]");
+	ut_asserteq(1, run_command(if_formatted, 0));
+
+	sprintf(if_formatted, if_format, "[ ''");
+	ut_asserteq(1, run_command(if_formatted, 0));
+	ut_assert_nextline(missing_rbracket_error);
+
+	sprintf(if_formatted, if_format, "[ 'abc' ]");
+	ut_assertok(run_command(if_formatted, 0));
+
+	sprintf(if_formatted, if_format, "[ 'abc'");
+	ut_asserteq(1, run_command(if_formatted, 0));
+	ut_assert_nextline(missing_rbracket_error);
+
 	return 0;
 }
 HUSH_TEST(hush_test_lbracket_alias, UTF_CONSOLE);
-- 
2.53.0



More information about the U-Boot mailing list