4

I'm using Debian 10 (Buster) and am getting an error in a simple Bash script. All it does is check to see if one parameter is passed in, and if it's a file, just echo out the file:

#!/usr/bin/bash
if [ ( '$#' -eq 1 ) && ( -f "$1" ) ]; then
        echo "$1"
fi

exit 1

I get this error:

line 2: syntax error near unexpected token `'$#''
line 2: `if [ ( '$#' -eq 1 ) && ( -f "$1" ) ]; then'

I have tried every combination of quotes (", ', no quotes) around the $#, and I always get a variant of those error messages using the type of quotes I use. I can't figure out what it's looking for.

  • 11
    You may find shellcheck.net helpful – roaima Sep 12 '19 at 11:56
  • 5
    You don't actually need the $# -eq 1 test. The -f test would be false if there was no argument. Also, you shouldn't exit 1 if the script is successful. – Kusalananda Sep 13 '19 at 10:30
11

[ 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
| improve this answer | |
20

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
| improve this answer | |
8

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
| improve this answer | |
  • 5
    And the fact that it's an if-statement doesn't matter, you could still define a function within it. if [ () { echo hello; }; then [; [; fi prints hello twice. – ilkkachu Sep 13 '19 at 13:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.