# Values from Commands: $( ) and $(( ))

$( ) runs a command and puts what it prints into another command or a variable, such as today's date in a backup's name, and $(( )) works out whole-number arithmetic, such as an age or a count plus one.

Apprentice · Unix · Linux · Updated November 10, 2026

## After this lesson you can

- Put a command's output into a variable or a name with $( ), such as today's date with date +%F
- Work out whole-number arithmetic with $(( )), with + - \* / and %

## Key takeaways

- $(command) runs the command and puts what it prints in its place. Read it "the output of".
- today=$(date +%F) keeps today's date, such as 2026-11-09, in a variable.
- A dated name such as "cards-$(date +%F).tar.gz" gives every day's backup its own file. Keep it in double quotes.
- $(( )) works out arithmetic with whole numbers. Names inside it need no $, and 17 / 5 is 3, with 17 % 5 the 2 left over.
- $(( )) can't do decimals. 7.5 is a syntax error.

You back up your photos every Sunday into `photos.tar.gz`, and every Sunday the new backup replaces last week's. You'd like `photos-2026-11-08.tar.gz`, then `photos-2026-11-15.tar.gz`, one file per week. Typing the date by hand works until you mistype it, and a script that runs at night has nobody to type it at all. The date is already one command away, though: `date` prints it. What you need is a way to put a command's output into another command. Administrators name every backup and log file this way, and every script that counts, totals or numbers things uses its arithmetic cousin.

The examples use the card shop from *Arguments: $1, $# and "$@"*: `cd ~/terminal-practice/cards`.

## $( ): a command's output, in place

`date` with a pattern prints the parts of the date you ask for. `+%F` (read "plus percent F", for *full date*) gives the year, month and day, in an order that also sorts by date when files are listed:

```bash
date +%F
```

```text
2026-11-09
```

Your date will be the day you run it. Now put that output inside another command. `$( )` (read "the output of") runs the command between the parentheses and puts what it printed in its place, before the outer command runs. This is **command substitution**:

```bash
echo "Made on $(date '+%A, %B %d, %Y')"
```

```text
Made on Monday, November 09, 2026
```

`%A` is the day's name, `%B` the month's, `%d` the day and `%Y` the year. *Dates and Times*, in Module 6, has the rest. You'll sometimes see the older form with backticks, `` `date +%F` ``; it does the same, but `$( )` is easier to read and can go inside another one.

## Keep it in a variable

`name=$(command)` keeps the output in a variable, so a script asks once and uses it many times:

```bash
today=$(date +%F)
echo "$today"
scripts=$(ls *.sh | wc -l)
echo "The card shop has $scripts scripts"
```

```text
2026-11-09
The card shop has 6 scripts
```

The second pair keeps the output of a whole pipeline: `ls` lists the scripts, and `wc -l` counts the lines. A trailing new line in the output is dropped, so the value fits neatly into a sentence.

## A backup with today's date in its name

Back to the problem from the start. Go up to `terminal-practice` and pack the card shop into an archive named after today, with `tar` from *Many Files as One: tar and zip*:

```bash
cd ~/terminal-practice
tar -czf "cards-$(date +%F).tar.gz" cards
ls *.tar.gz
```

```text
cards-2026-11-09.tar.gz
```

Tomorrow the same line makes `cards-2026-11-10.tar.gz` beside it, and nothing is replaced. Run it twice on the same day, and the second run replaces that day's archive with a fresh one. The double quotes are the habit from *Quotes: Double, Single and None*: if the output ever has a space in it, the name stays one piece. Go back with `cd cards`.

## $(( )): whole-number arithmetic

Bash can do sums, too. `$(( ))` (read "the arithmetic of") works out the arithmetic between the double parentheses and puts the answer in its place. This is **arithmetic expansion**. Inside it, a variable's name needs no `$`, and you can put `$( )` inside it:

```bash
echo $(( 2026 - 1996 ))
born=1996
echo "Happy $(( $(date +%Y) - born ))th birthday, Maya!"
guests=12
echo "Cards to buy: $(( guests * 2 + 1 ))"
```

```text
30
Happy 30th birthday, Maya!
Cards to buy: 25
```

`+` adds, `-` subtracts, `*` (read "times") multiplies and `/` divides, with multiplication before addition, as in math class. Bash works in whole numbers only. Dividing drops what's left over, and `%` (read "remainder") gives it to you: 17 cards in packs of 5 make 3 full packs, with 2 cards left over.

```bash
echo $(( 17 / 5 )) $(( 17 % 5 ))
echo $(( 7.5 * 2 ))
```

```text
3 2
bash: 7.5 * 2 : arithmetic syntax error: invalid arithmetic operator (error token is ".5 * 2 ")
```

A decimal point is an error. For money with cents, hand the sum to `awk` from *Columns and Totals: awk*: `awk 'BEGIN { print 7.5 * 2 }'` prints `15`. zsh at a Mac's prompt knows both `$( )` and `$(( ))`.

## Check yourself

2 questions to try on the lesson page.

## So what

`$( )` lets a script use any command's answer as a value, today's date in a backup's name above all, and `$(( ))` does the whole-number sums: an age, a count, one more than the last.

## Key terms

- [Command Substitution](https://www.ask-codey.com/glossary/command-substitution)
- [Arithmetic Expansion](https://www.ask-codey.com/glossary/arithmetic-expansion)
- [date](https://www.ask-codey.com/glossary/date)

## Cheat sheets

- [Values from Commands: $( ) and $(( ))](https://www.ask-codey.com/cheat-sheets/bash-command-substitution-cheat-sheet)

## Related

- [Quotes: Double, Single and None](https://www.ask-codey.com/lessons/bash-quoting)
- [Many Files as One: tar and zip](https://www.ask-codey.com/lessons/bash-archives)
- [Arguments: $1, $# and "$@"](https://www.ask-codey.com/lessons/bash-script-arguments)

Source: https://www.ask-codey.com/lessons/bash-command-substitution
