Bash – What does “echo (ls)” do in bash

bashecho

When I run echo (ls) in bash it returns:

-bash: syntax error near unexpected token `ls'

I understand that I should escape parenthesis or quote to get plain text output.
But the result still does not make sense to me if parenthesis means running the command sequence in a subshell environment.

My environment: bash 4.3 (installed by homebrew), OS X El Capitan

Best Answer

It is essentially a generic syntax error, not specifically related to the ls token. bash uses a yacc parser, which calls a common yyerror() on any problem, Within the resulting error-handling, it proceeds to try to pinpoint the error. The message is coming from this chunk (see source):

  /* If the line of input we're reading is not null, try to find the       
     objectionable token.  First, try to figure out what token the
     parser's complaining about by looking at current_token. */
  if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
    {
      if (ansic_shouldquote (msg))
    {
      p = ansic_quote (msg, 0, NULL);
      free (msg);
      msg = p;
    }
      parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
      free (msg);

      if (interactive == 0)
    print_offending_line ();

      last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
      return;
    }

In other words, it's already confused by the '(', and having looked-ahead for context is reporting the ls.

A ( would be legal at the beginning of a command, but not embedded. Per manual page:

   Compound Commands                                                       
       A compound command is one of the following:

       (list) list  is  executed in a subshell environment (see COMMAND EXECU‐
              TION ENVIRONMENT below).  Variable assignments and builtin  com‐
              mands  that  affect  the  shell's  environment  do not remain in
              effect after the command completes.  The return  status  is  the
              exit status of list.

Further reading:

Related Question