Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a space in a variable assignment give an error in Bash? [duplicate]

#!/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?

like image 511
SaiKiran Avatar asked Jan 19 '17 17:01

SaiKiran


3 Answers

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
like image 107
Charles Duffy Avatar answered Nov 19 '22 16:11

Charles Duffy


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.

like image 43
Richard Hamilton Avatar answered Nov 19 '22 14:11

Richard Hamilton


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.

like image 2
Fred Avatar answered Nov 19 '22 16:11

Fred