echo "*file 2" | grep -o ^.
prints *
.
Since you have a command substitution outside double quotes, it undergoes globbing (a.k.a. wildcard matching a.k.a. filename generation) and word splitting. If the current directory is not empty, *
expands to the list of files in the current directory. Each file becomes one token in the [
command, which is highly likely to be a syntax error.
The problem is that you didn't use double quotes around the command substitution. Always use double quotes around variable and command substitutions unless you have a good reason to omit them.
if [ "$(echo "*file 2" | grep -o ^.)" = '.' ]
See Why does my shell script choke on whitespace or other special characters? for a more detailed explanation.