Read

Module 9 · Shell scripting basics

Command substitution and arithmetic

Capture a command's output into a variable with $( ), and do integer maths with $(( )) instead of reaching for a calculator.

What you will learn

  • Use `$(command)` to store output in a variable or embed it in a string.
  • Do integer arithmetic with `$(( ))` and know its limits.
  • Combine both to build small reports.

So far variables got their values from you. The real power comes when a variable gets its value from another command. $(command) runs the command, takes whatever it printed, trims the trailing newline, and drops the text right there in your line. The old spelling with backticks, ` command , does the same but nests badly; prefer $( )`.

~% today=$(date +%Y-%m-%d)
~% echo "Backup for $today"
Backup for 2026-10-04
~% files=$(ls /etc | wc -l)
~% echo "/etc has $files entries"
/etc has 24 entries
~% echo "Kernel $(uname -r) on $(hostname), up $(cut -d' ' -f1 /proc/uptime) s"
Kernel 4.16.13 on (none), up 312.45 s
~% cp report.txt "report-$(date +%H%M).txt"

Anything that prints can feed a variable: wc -l, grep -c, date, cat file, a pipeline. Quote the substitution when you use it, "$(…)", for the same reason you quote variables: the output might contain spaces or newlines, and unquoted it gets split into words.

Arithmetic with $(( ))

The shell stores text, but $(( expression )) evaluates the expression as integer arithmetic and gives back the result as text. Inside the double parentheses you can write variable names without $, and the usual operators work: + - * / %, comparisons, parentheses. Division truncates: $(( 10 / 3 )) is 3, and $(( 10 % 3 )) is the remainder 1. There are no decimals; for those you would pipe to awk.

~% a=7; b=3
~% echo $(( a + b )) $(( a * b )) $(( a / b )) $(( a % b ))
10 21 2 1
~% echo $(( (a + b) * 2 ))
20
~% n=0; n=$(( n + 1 )); n=$(( n + 1 )); echo $n
2
~% kb=$(du -sk /etc | cut -f1)
~% echo "/etc uses $kb KB, about $(( kb / 1024 )) MB"
/etc uses 12 KB, about 0 MB
~% echo $(( 2 ** 10 ))
1024

The pattern n=$(( n + 1 )) is how you count in a loop; you will use it constantly from lesson 86 on. Comparisons inside $(( )) give 1 for true and 0 for false, but for decisions in scripts you will normally use test (next lesson) instead.

SyntaxMeaningExample
$(cmd)Output of a commandnow=$(date +%T)
$(( expr ))Integer arithmetic$(( total / count ))
${var}A variable's value${name}_v2
expr 2 + 3Old external calculator; spaces requiredexpr $a \* 2

One practical detail: wc -l file prints the count and the file name, while wc -l < file prints only the count, which is what you want inside $(( )). The same trick works for wc -c to get a file size in bytes without stat, which this BusyBox does not have.

Commands in this lesson

CommandWhat it does
var=$(command)Store a command's output.
echo "Now: $(date)"Embed output inside a string.
$(( a + b ))Integer arithmetic.
n=$(( n + 1 ))Increment a counter.
wc -l < fileLine count only, no file name.
expr 2 + 3Legacy arithmetic command.

Quiz

  1. What does `n=$(ls /etc | wc -l)` leave in `n`?

    • The text `ls /etc | wc -l`
    • The number of entries in /etc
    • An error: pipes are not allowed in $( )
  2. What is `$(( 7 / 2 ))`?

    • `3.5`
    • `3`
    • `4`
  3. Which line correctly adds one to `count`?

    • `count=count+1`
    • `count=$(count + 1)`
    • `count=$(( count + 1 ))`
  4. Why quote a substitution, as in `echo "$(cat f)"`?

    • To keep spaces and newlines in the output intact
    • Because $( ) does not work without quotes
    • To make it run faster

Practice

  1. Write an executable script `/root/lab/l83/count.sh` that prints `Files: N`, where N is the number of entries in `/root/lab/l83/data` (use `ls | wc -l` inside `$( )`).

  2. Write an executable script `/root/lab/l83/sum.sh` that prints the sum of its two arguments: `./sum.sh 17 25` prints `42`. (Inside a script, `$1` and `$2` are the first two arguments; more in lesson 88.)

  3. Using command substitution, write the current year (four digits, from `date +%Y`) into `/root/lab/l83/year.txt`.

Open this lesson in the app to do the tasks in a real Linux machine and have them checked.