windchime
windchime

Reputation: 1285

Output of $(3-1) in bash

I found one thing I can not explain in bash.

Command:

$(3-1)
3-1: command not found

If I do it step by step, it will show as follows:

3-1
3-1: command not found

3-1: command not found
3-1:: command not found

Double colons there. Why is the difference?

Upvotes: 0

Views: 132

Answers (6)

Sergey Fedorov
Sergey Fedorov

Reputation: 2169

what are you going to do with 3-1? if you want to execute it I doubt you have program 3-1 or 2. try like this:

n=$((3-1))
echo $((3-1))

I think explanation is needed here:

if you write in bash new line

do_smth

it assumes you want to execute a program. The $(do_smth) mean: execute a program do_smth and catch the output. so, if you write in bash new line

$(do_smth)

it assumes you want to execute do_smth, take an output from command and execute command with name it get. $(( $do_smth )) is another. It assumes $do_smth is a mathematical expression and affords you to calculate c-like math expression.

Upvotes: 2

thom
thom

Reputation: 2332

The shell sees this:

situation 1

stdin-      "$(3-1)"   ( run non existent command "3-1" in a subshell ... )
Command-    "3-1"
Arguments- 
error-      3-1
reply-      "3-1" ": command not found"

situation 2

stdin-      "3-1:" "command" "not" "found"
Command-    "3-1:"            
                 (note that the ":" you typed is seen as part of the command)
Arguments-  "command" "not" "found"
error-      3-1:
reply-      "3-1:" ": command not found"
               (^---^ and this is where the double colon comes from)

As you can see, the shell does not reply with a double colon at all!

it echoes your "3-1:" and it adds ": reply"

Upvotes: 0

user2404501
user2404501

Reputation:

Your "step by step" breakdown is wrong because you assumed that the first "command not found" error message would become the result of the $() and therefore be re-parsed as a command. This doesn't happen because $() only captures standard output (fd 1) and the "command not found" message is printed to standard error (fd 2).

If you run

$(3-1 2>&1)

you might get something more like what you're expecting. (I can't reproduce your result exactly because my bash error messages don't look quite like yours.)

Upvotes: 0

choroba
choroba

Reputation: 241968

3-1 is not found. The error message you get is sent to standard error, not standard output. So, $(3-1) is not running

3-1: command not found

It is running 3-1 and failing. If you try to run the error message, the first word is taken as the command, the rest are the arguments. The command 3-1: is not found either, hence the error message with two colons.

Upvotes: 2

chepner
chepner

Reputation: 531758

When you type any command which bash cannot find, you get an error message of the form

bash: <cmd>: command not found

So if you type 3-1, you get

$ 3-1
bash: 3-1: command not found

If you type 3-1:, you get

$ 3-1:
bash: 3-1:: command not found

Upvotes: 0

Kent
Kent

Reputation: 195179

you input:

foo

output:

foo: command not found

you input :

foo bar

output:

 foo: command not found

so bash thinks the space separating commands/parameters. If the command you gave with :, you get it in input too:

input:

foo:

output:

foo:: command not found

replace foo with 3-1, you find the answer.

Upvotes: 0

Related Questions