[: =: unary operator expected means a variable inside [ ] was empty and not quoted, so the test lost one of its words. Put double quotes around the variable, [ "$name" = "admin" ], and the test works with an empty value.

The script did not stop at the error: it took the else branch and exited with 0, so the mistake is easy to miss in a log.

The error

docker exec fix10-lc-u3 bash -c 'cat /root/role.sh'
#!/bin/bash
name="$1"
if [ $name = "admin" ]; then
  echo "welcome, admin"
else
  echo "not admin"
fi

docker exec fix10-lc-u3 bash -c 'cd /root; bash role.sh 2>&1; echo exit=$?'
role.sh: line 3: [: =: unary operator expected
not admin
exit=0

Why it happens

The script was run with no argument, so name was an empty string, and the unquoted $name left no word at all. bash -x prints each command as it runs, and shows what [ was given: = and admin, two words instead of three.

docker exec fix10-lc-u3 bash -c 'cd /root; bash -x role.sh 2>&1'
+ name=
+ '[' = admin ']'
role.sh: line 3: [: =: unary operator expected
+ echo 'not admin'
not admin

[ returned a failure, the if treated that as false, and the script printed not admin and finished with exit code 0. In this test the message appeared only in the run with the empty value; the runs with a real value, shown in the fix below, printed no error.

The fix

docker exec fix10-lc-u3 bash -c 'cd /root; sed -n 3p role2.sh; bash role2.sh 2>&1; echo exit=$?; bash role2.sh admin 2>&1'
if [ "$name" = "admin" ]; then
not admin
exit=0
welcome, admin

role2.sh is the same script with $name in double quotes on line 3. With no argument it now prints not admin without an error, and with admin it takes the other branch, so the behaviour for a real match is the same as before. The -x trace above is the quickest way to see which variable came out empty when a longer script fails this way. A value with a space in it breaks the unquoted line differently; that case has its own post, linked below.

How it was reproduced

The capture was made in an ubuntu:24.04 container (Ubuntu 24.04.5 LTS, bash 5.2.21) on Docker Engine 29.9.3, started with docker run -d --name fix10-lc-u3 ubuntu:24.04 sleep infinity. Both scripts were copied in with docker cp l3\role.sh fix10-lc-u3:/root/role.sh (and the same for role2.sh). Every command was sent from Windows PowerShell 5.1 as shown, with the bash -c text in single quotes so it reached the container unchanged. The container name is the test's own.

Frequently asked

What does unary operator expected mean in bash?
A variable in a [ ] test was empty and unquoted, so the test had one word too few. In the test [ $name = "admin" ] with an empty name printed this message.
How do I fix [: =: unary operator expected?
Put the variable in double quotes: [ "$name" = "admin" ]. In the test the quoted version printed not admin without an error.
Does the script stop at unary operator expected?
No. In the test the if took the else branch and the script exited with code 0, so check logs for the message itself.

More decoded errors in the Fixes category. The same unquoted variable holding two words gives [: too many arguments.