mimoralea mimoralea - 2 months ago 10
Bash Question

Expr and date in shell and in a variable

So, I do:

expr `date +%d` - 1


In sh shell and it correctly respond
11
.

But if I want to store that in a variable:

-sh-4.2# NUMBER=expr `date +%d` - 1
-sh: 12: command not found
-sh-4.2# NUMBER=$((expr `date +%d` - 1))
-sh: expr 12 - 1: syntax error in expression (error token is "12 - 1")
-sh-4.2# NUMBER="expr `date +%d` - 1"
-sh-4.2# echo $NUMBER
expr 12 - 1
-sh-4.2# $NUMBER
11
-sh-4.2#


It just doesn't give me what I'm looking for. I want:


echo $NUMBER


to say
11
, not to evaluate to 11?

My questions are:


  1. Why does my first attempt not work?

  2. How can I make it happen?



BTW, I'm limited to /bin/sh
GNU bash, version 4.2.10(1)-release (mipsel-unknown-linux-uclibc)

EDIT:
AND, date is very limited.
BusyBox v1.19.4 (2013-10-30 00:56:51 PDT) multi-call binary.
/EDIT

Although, it is bash it is limited since it is an embedded platform.

Answer

I think this is what you're looking for:

$ NUMBER=$(expr `date +%d` - 1) 
$ echo $NUMBER
11
$ 

This works because expr is a command which is evaluated. To get the output of an evaluated command, you can use $() command expansion or backticks

Or

$ NUMBER=$(expr $(date +%d) - 1)
$ echo $NUMBER
11
$

This is pretty much equivalent to the first example. Note $() is preferable to backticks because it is easily nestable without escaping quotes.

Or

$ NUMBER=$(($(date +%d) - 1))
$ echo $NUMBER
11
$ 

We can also do arithmetic directly in the shell without the expr command, using $(( )) arithmetic expansion. See the Arithmetic Expansion section of the Advanced Bash-Scripting Guide


Update

Since you're using busybox, you can use this mouthful to do the date arithmetic correctly, even when it is the 1st of the month:

$ type date
date is aliased to `busybox date'
$ NUMBER=$(date -D %s -d $(($(date +%s) - 86400)) +%d)
$ echo $NUMBER
11
$ 

This breaks in 2038 though due to the Unix Epoch Year 2038 problem, so please don't implement this in a nuclear power station or space station or something ;-)