2

I have a very surprising problem while trying to execute a diff command inside a bash script.

Here is a working code illustrating the point:

#!/bin/bash
cd
mkdir foo bar
head -c 1024 /dev/urandom >foo/qux
head -c 1024 /dev/urandom >bar/qux

# works properly as expected
diff ~/{foo,bar}/qux

folder="~"

# this fails with the ~ inside a variable
diff $folder/{foo,bar}/qux

# cleaning the mess
rm -rf foo bar

So my question is:

Why ? :-)

Romain Vincent
  • 2,875
  • 2
  • 22
  • 29

3 Answers3

2

Don't quote the ~ when assigning it to a variable. The ~ is only expanded by bash when you don't quote it.

1

~ is a feature of shell expansion.
Double quotes limit the expansion to only three features:

  1. Command substitution: $(some command here) or `some command here`
  2. Variable substitution: $VAR or ${VAR}
  3. Arithmetic: $((2+2))

so when put inside double quotes, the ~ is not expanded

Romain Vincent
  • 2,875
  • 2
  • 22
  • 29
hedgar2017
  • 1,425
  • 3
  • 21
  • 40
1

Tilde expansion only applies to unquoted tildes. The tilde must be expanded at the time you perform the assignment to folder, because tilde expansion is not applied to parameter expansions, only word splitting and pathname expansion.

folder=~  # ~ is expanded, and the result is assigned to folder
chepner
  • 497,756
  • 71
  • 530
  • 681