191

I have two questions and could use some help understanding them.

  1. What is the difference between ${} and $()? I understand that () means running command in separate shell and placing $ means passing the value to variable. Can someone help me in understanding this? Please correct me if I am wrong.

  2. If we can use for ((i=0;i<10;i++)); do echo $i; done and it works fine then why can't I use it as while ((i=0;i<10;i++)); do echo $i; done? What is the difference in execution cycle for both?

Yan King Yin
  • 1,189
  • 1
  • 10
  • 25
Anaadih.pradeep
  • 2,453
  • 4
  • 18
  • 25
  • It is a 2 part question. "Backticks vs. braces" just happens to have answers for both? If it answers 1, ask OP to edit it so that it is a standard, singular question. – Nate T Sep 11 '21 at 08:31

3 Answers3

262

The syntax is token-level, so the meaning of the dollar sign depends on the token it's in. The expression $(command) is a modern synonym for `command` which stands for command substitution; it means run command and put its output here. So

echo "Today is $(date). A fine day."

will run the date command and include its output in the argument to echo. The parentheses are unrelated to the syntax for running a command in a subshell, although they have something in common (the command substitution also runs in a separate subshell).

By contrast, ${variable} is just a disambiguation mechanism, so you can say ${var}text when you mean the contents of the variable var, followed by text (as opposed to $vartext which means the contents of the variable vartext).

The while loop expects a single argument which should evaluate to true or false (or actually multiple, where the last one's truth value is examined -- thanks Jonathan Leffler for pointing this out); when it's false, the loop is no longer executed. The for loop iterates over a list of items and binds each to a loop variable in turn; the syntax you refer to is one (rather generalized) way to express a loop over a range of arithmetic values.

A for loop like that can be rephrased as a while loop. The expression

for ((init; check; step)); do
    body
done

is equivalent to

init
while check; do
    body
    step
done

It makes sense to keep all the loop control in one place for legibility; but as you can see when it's expressed like this, the for loop does quite a bit more than the while loop.

Of course, this syntax is Bash-specific; classic Bourne shell only has

for variable in token1 token2 ...; do

(Somewhat more elegantly, you could avoid the echo in the first example as long as you are sure that your argument string doesn't contain any % format codes:

date +'Today is %c. A fine day.'

Avoiding a process where you can is an important consideration, even though it doesn't make a lot of difference in this isolated example.)

Chad
  • 1,750
  • 2
  • 16
  • 32
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 4
    Strictly, a `while` command expects a sequence of commands (not necessarily a pipeline), and the exit status of the last command in the sequence determines whether the loop continues or not. Thus: `while ls; pwd; date; do echo Hi; sleep 1; done` is valid, and the exit status of `date` controls whether the loop continues or not. I used semicolons because you can't format newlines in a comment, but you could write the commands on multiple lines in a shell script. – Jonathan Leffler Dec 14 '14 at 19:46
  • I'm flabbergasted that this answer continues to receive upvotes; it's not particularly stellar. If you upvoted this, would you care to explain which part of it is useful? I guess the relationship between `for` loops and `while` loops isn't entirely obvious (I remember liking it when I first read it in on the first edition of the Perl *Camel Book)* but is there anything other than that ...? – tripleee Apr 09 '18 at 06:40
  • 1
    There's also the issue of 'well, the other two answers are not better'. – Jonathan Leffler Apr 09 '18 at 07:56
  • @JonathanLeffler Heh, maybe just abstain from voting then (-: – tripleee Apr 09 '18 at 08:03
  • @tripleee Why don't you want the upvotes? Anyway I often upvote answers because if they are helpful (in this case I needed to know the difference between $() and ${}) regardless of whether they are _stellar_... – Ben Jones Aug 07 '18 at 21:11
  • @BenJones Thanks for following up! I don't particularly mind the upvotes per se, I'm just baffled if this is a common question for people to have, or if this post on Stack Overflow is the one they are drawn to for an answer. (But I guess the title helps, and the distraction with a second unrelated question in the same post is easy to ignore, even if it's still a distraction.) – tripleee Aug 08 '18 at 03:43
99
  1. $() means: "first evaluate this, and then evaluate the rest of the line".

    Ex :

    echo $(pwd)/myFile.txt
    

    will be interpreted as

    echo /my/path/myFile.txt
    

    On the other hand ${} expands a variable.

    Ex:

    MY_VAR=toto
    echo ${MY_VAR}/myFile.txt
    

    will be interpreted as

    echo toto/myFile.txt
    
  2. Why can't I use it as bash$ while ((i=0;i<10;i++)); do echo $i; done

    I'm afraid the answer is just that the bash syntax for while just isn't the same as the syntax for for.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
gturri
  • 13,807
  • 9
  • 40
  • 57
-1
  1. your understanding is right. For detailed info on {} see bash ref - parameter expansion

  2. 'for' and 'while' have different syntax and offer different styles of programmer control for an iteration. Most non-asm languages offer a similar syntax.

With while, you would probably write i=0; while [ $i -lt 10 ]; do echo $i; i=$(( i + 1 )); done in essence manage everything about the iteration yourself

Dinesh
  • 4,437
  • 5
  • 40
  • 77
  • Not my down-vote, but the OP seems to be confusing `(command …)` with `$(commnd …)`, which are quite different in detail, though they share some commonality too. Thus, your first observation is not entirely accurate; the OP's understanding is not entirely correct. – Jonathan Leffler Dec 14 '14 at 19:48
  • 3
    _Most non-asm languages offer a similar syntax._ What??? – gniourf_gniourf Dec 14 '14 at 20:52
  • @gniourf_gniourf FOR syntax. In most non-assembly languages (in my limited knowledge), not counting some ancient ones like algol – Dinesh Dec 15 '14 at 00:44
  • @JonathanLeffler thanks for clarifying. I too thought so but figured that in the context OP had not meant a subshell. – Dinesh Dec 15 '14 at 00:48