3

I was trying to uppercase the output of date command in bash (GNU bash, version 5.0.17).

date +"%d%m%Y"
# 30Dec2020

I came across ^^ operator for uppercase which is used as

DT="$(date +"%d%b%Y")"
echo ${DT^^} # works with curly braces
# 30DEC2020

echo $(DT^^) # fails with brackets
bash: DT^^: command not found

I'm not familiar with the ${} how is this different from $(). I did look it up online and they both seem to do the same thing ie. variable expansion. Thanks in advance.

3

1 Answer 1

8

Curly braces with a dollar sign (${}) are for pre-established variables. Take the a look at the following example:

ThisIsAVariable=abc
echo ${ThisIsAVariable}
echo $ThisIsAVariable

Those last to commands would print the same thing: abc. However, being able to wrap variables in curly braces is quite useful in some cases. For example, if a script has two variables next to eachother, the curly braces help cleanly separate one variable from another. For instance:

echo ${ThisIsAVariable}${PWD}

Both the shell and any human who reads this script will be able to easily see that "ThisIsAVariable" and "PWD" are two different variables.

Curly braces are also important because they are the only way to work with variable arrays. Let's suppose we were in a directory that had the following files 1.txt, 2.txt, and 3.txt. With that in mind, consider the following:

file[0]=1.txt
file[1]=2.txt
file[2]=3.txt
echo $file
echo ${file[2]}

Those first three commands wouldn't have any output, as they are only setting variables. However, the fourth command would print 1.txt. That variable was called without explicitly telling the shell which array # to print, so it defaulted to #0. The fifth line is the most interesting, because it will print 3.txt. What I did was call the file variable with array #2 which - as we can see - was declared as 3.txt.

You can do other things with braces as well:

x=123-45
echo ${x//-*}
echo $x

That second-to-last command basically translates as "remove everything after the hyphen". So, while x still equals the string 123-45, the -45 was filtered out. The last command outputs 123-45 as we would expect.

There's plenty more to learn about brace expansion, but... well... I haven't learned that yet, so I can't even begin to teach that.

That said, parenthesis with a dollar sign ($()) is for command substitution, which is entirely different. Basically, process substitution is for letting one command generate the parameters of another. Take a look at this example:

ls
ls -l
ls $(echo -l)

Once again, you'll notice the last two commands had the same output. This is because, on the last line, echo gave ls a -l argument, making it essentially the same as the command above it. Sometimes, you just need the output of one program to become the input of another in order to automate something or another. This can be tricky, but luckily *nix shells like BASH give you plenty of ways to make that happen. (I won't mention them, as they are beyond the scope of this question, but if you are willing to find somewhere to learn, you will become AN ALL POWER WIZARD in no time. And that's good fun.)

5
  • I'm used to seeing the curly braces when inserting variables in a longer string. Didn't recognise it on it own :) But then why doesnt echo $DT^^ work without curly braces? Either ways you answered my question. Thanks
    – Bob
    Dec 30, 2020 at 6:43
  • I probably should have mentioned in my answer that curly braces are also used for variable arrays. I guess I'll add that. BTW, I'm not 100% sure those ^^ characters do anything at all. Dec 30, 2020 at 7:20
  • 1
    @Bob ${DT^^} is a variable substitution (in the bash shell only) that up-cases all characters in the value of the variable DT. There are a number of other variable substitutions, like ${DT#2020} to remove the string 2020 from the start of $DT. See e.g. mywiki.wooledge.org/BashGuide/Parameters#Parameter_Expansion
    – Kusalananda
    Dec 30, 2020 at 7:24
  • If you have a=XYZ, consider echo "$abc" and echo "${a}bc" Dec 30, 2020 at 9:23
  • Also, with id=hello, consider a=${id}; echo "$a" and a=$id; echo "$a" and a=$(id); echo "$a" Dec 30, 2020 at 9:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .