Bash error: conditional binary operator expected
"conditional binary operator expected" means [[ ]] saw two operands and no operator — usually an unquoted pattern with spaces. Worked fixes for each case.
Error String
bash: conditional binary operator expected
Tldr
A `[[ ]]` test parsed something that looked like an operand followed by another operand with no operator between them. Common causes: stray whitespace in a regex, `=~` with an unquoted pattern containing spaces, or a typo like `[[ $a $b ]]`.
Cause
Inside `[[ ]]`, the right side of `=~` is a regex and should not be quoted (quoting turns it into a literal in modern Bash). If the regex contains spaces, store it in a variable.
Repro
[[ $x =~ ^[A-Z] +$ ]] # space in regex breaks parsingFix
pattern='^[A-Z] +#39;
[[ $x =~ $pattern ]] && echo matchExplanation
Always put complex regexes in a variable and use `$var` (unquoted) inside `=~`. This avoids both this error and the quote-vs-literal pitfall.
Faq
Q
Why does the same test work with a one-word value?
A
Word splitting only produces extra operands when the value contains whitespace, so the bug hides until real data arrives.
Q
Is `[[ ]]` portable?
A
It is Bash, ksh and zsh only — not POSIX `sh`. Use quoted `[ ]` where `/bin/sh` compatibility matters.
Deep Dive
Heading
Unquoted expansions break the test into extra words
Body
The message means `[ ... ]` received more words than a comparison can use. Almost always a variable containing spaces was left unquoted: `[ $name = bob ]` with `name="two words"` becomes `[ two words = bob ]`, and the test sees a second operand where an operator should be. Quoting the expansion — `[ "$name" = bob ]` — makes it one word again. An empty variable causes the mirror-image failure, an operator with nothing before it.
Heading
Prefer [[ ]] in Bash
Body
`[[ ]]` is a shell keyword rather than a command, so it does not word-split unquoted expansions and it supports `==` pattern matching and `=~` regular expressions. Keep quoting anyway for consistency, and keep patterns unquoted when you want them to match as patterns. If the script must be POSIX `sh`, stay with `[ ]` and quote every expansion, using `[ "x$var" = "xvalue" ]` when the value could begin with a dash.
Checklist
Quote every variable inside the test.
Print the variable with `printf "[%s]\n" "$var"` to reveal spaces.
Switch to `[[ ]]` when the script is Bash-only.
Handle the empty case explicitly with `[ -z "$var" ]`.