12
#!/bin/bash

declare -r NUM1=5
NUM2 =4                # Line 4

num3=$((NUM1 + NUM2))
num4=$((NUM1 - NUM2))
num5=$((NUM1 * NUM2))
num6=$((NUM1 / NUM2))  # Line 9

echo "$num3"
echo $((5**2))
echo $((5%4)) 

I am using this bash script, and when I was running the script, I got the error

./bash_help 
./bash_help: line 4: NUM2: command not found
./bash_help: line 9: NUM1 / NUM2: division by 0 (error token is "NUM2")
5
25
1

So I have changed the code to this and the error was gone.

#!/bin/bash

declare -r NUM1=5
NUM2=4

num3=$((NUM1 + NUM2))
num4=$((NUM1 - NUM2))
num5=$((NUM1 * NUM2))
num6=$((NUM1 / NUM2))

echo "$num3"
echo $((5**2))
echo $((5%4)) 

Why can't we use spaces when we assign a value to a variable? It is convention to use spaces for better readability of the code. Can anyone explain this?

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
SaiKiran
  • 6,244
  • 11
  • 43
  • 76
  • 1
    It is just one of those paradigms in `bash`, you can't question it – Inian Jan 19 '17 at 17:55
  • 3
    In shell, spaces are important delimiters. In most cases, you **cannot** add or remove them to make things look better, because they change the meaning of the command line. – Gordon Davisson Jan 19 '17 at 17:58
  • Thanks,though it is a small issue.clarity gives less errors. – SaiKiran Jan 19 '17 at 17:59
  • 2
    Clarity and backwards compatibility rarely go together. POSIX sh was first published in 1991, and its roots go back to the 1970s. Just as Common LISP is an ugly and highly useful behemoth cobbled together from historical LISPs and Scheme is tiny, beautiful, and utterly lacking a practical ecosystem of libraries, bash is on the former (old, ugly and useful) side of this divide. – Charles Duffy Jan 19 '17 at 17:59
  • BTW, http://shellcheck.net/ will catch this class of error for you automatically; it's well worth using (for that matter, it's possible to install it locally, and have your editor run it automatically as you work). – Charles Duffy Jan 19 '17 at 21:54

3 Answers3

24

It's not a convention in bash (or, more generally, POSIX-family shells).

As for "why", that's because the various ways of doing it wrong all have valid meanings as commands. If you made NUM2 = 4 an assignment, then you couldn't pass = as a literal argument without quoting it. Consequently, any such change would be backwards-incompatible, rather than being placed in undefined space (where extensions to the POSIX sh standard need to live to avoid constituting violations of that standard).

NUM2= 4 # runs "4" as a command, with the environment variable NUM2 set to an empty string
NUM2 =4 # runs "NUM2" as a command, with "=4" as its argument
NUM2 = 4 # runs "NUM2" as a command, with "=" as its first argument, and "4" as another
chepner
  • 497,756
  • 71
  • 530
  • 681
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
3

In Bash, functions are passed arguments as whitespace separated words.

From the documentation

"Each operator and operand must be a separate argument."

Variable assignment is different and uses this syntax name=[value]

The reason you can't put unquoted spaces around the equals sign is because bash would interpret this as a command.

Richard Hamilton
  • 25,478
  • 10
  • 60
  • 87
3

The reason is, quite simply, that the shell is built to behave like this. It may not make sense for someone with experience in other programming languages (if you call shell syntax a "language", which in a sense it is).

Shell scripting makes it possible in many cases to simply not quote strings (as long as a sequence of characters meant to be a single string does not contain any spacing or special characters). Thanks to this, you can write :

 my_command -n -X arg1 arg2

Instead of (in some kind of imaginary pseudo code)

 "my_command" "-n" "-X" "arg1" "arg2"

In most languages, it is the other way around : literal strings are quoted, which frees "syntax space" for using variables without any special character (like $ in shell scripting).

Shell syntax provides convenience in frequent cases, at the cost of, well, less convenience (and readability) when doing some other things. It is both a curse and a blessing. The nice thing is knowing that if you have an interactive shell, you can be 100% sure you have an interpreter that will handle some kind of (maybe inelegant) programs. Due to its universal availability (despite various flavors being in existence), the shell is a kind of platform that is useful enough to be worth learning.

Fred
  • 6,590
  • 9
  • 20