%N is an extension of the GNU implementation of date (added in 4.5.1 in 2002).
It is now also supported by
- ast-open's
date since version 2005-01-11 - busybox
date since 1.17.0 (2010), though it's optional there and generally not enabled by default - toybox
date since 0.7.4 (2017). - FreeBSD
date since 14.1 (2024)
But generally not other implementations.
Here, it seems your date doesn't support %N and upon date +%N outputs N (a behaviour I can reproduce with FreeBSD before 14.1, and probably what you'd get in macos as well).
So that:
let "time_taken=$before-$after"
(btw ITYM after-before) becomes something like:
let 'time_taken=10#1590683503N-10#1590683504N'
And bash complains about that N which can't be used in base 10.
In any case, running date itself will take thousands of nanoseconds, so having that much precision probably don't make much sense.
Here, you could switch to zsh where, like in ksh93, the $SECONDS special variable can be made a floating point number and simply do:
#! /bin/zsh - typeset -F SECONDS=0 sleep 1 time_taken=$SECONDS
Or use the $epochtime array variable of the zsh/datetime module which contains seconds and nanoseconds as 2 separate integers:
#! /bin/zsh - zmodload zsh/datetime || exit before=($epochtime) sleep 1 after=($epochtime) (( time_taken_ns = 1_000_000_000 * (after[1] - before[1]) + after[2] - before[2] ))
dateimplementation doesn't support the%Nformat specifier, and is rendering it as literalN?Nin the error message there. In base 24,Nwould be a valid digit... As an aside, I don't think you should need10#here, the output ofdate +%sshould not have leading zeroes (unlike months, days, hours and minutes often have)$SECONDSvariable.real 0m3.740s. You may need some inventive subshelling to capture it.