I am getting "syntax error near unexpected token `'$#''" in a simple Bash script

There are two issues here. First, the simple [ builtin can't contain &&. If you want to combine multiple conditions, you need multiple [:

if [ "$#" -eq 1 ] && [ -f "$1" ]; then

Second, you can't use single quotes around the $# since that needs to be expanded. Your version, with '$#' -eq 1 was comparing the string $# to the number 1.

The whole thing is much simpler if you use bash's [[ keyword instead:

if [[  "$#" -eq 1  &&  -f "$1"  ]]; then

[ is a command, so the problem is really the way you're trying to use multiple conditions. You want this:

if [ "$#" -eq 1 ] && [ -f "$1" ]; then

Despite the other answers explaining how to fix the script, I wondered what the error was technically about. I think the only valid syntax where bash allows a word in a command to be an unquoted and unescaped ( is when defining functions. So, bash saw ( and immediately thought it had to be a definition for a function named [, but then you followed with '$#' and bash was only expecting ), so that's why you got that syntax error. If it wasn't meant to be a function definition, then who knows what it was meant to be. Anything else after ( besides ) would have raised the same syntax error:

$ echo ( foo )
bash: syntax error near unexpected token `foo'

If you remove what follows ( that doesn't fit the syntax of a function definition, you get:

$ [ ( ) ( -f "$1" )

Which ends up defining the function [:

$ [
bash: -f: command not found

Tags:

Syntax

Bash