Can not evoke watch command with non-integer time option
This is a locale problem. watch
uses strtod(3)
, which is locale-dependent, to convert the argument to -n
to a double
.
To fix the problem, you need to either specify the argument to -n
with a different separator:
watch -n 0,1 w
Or change your locale to a setting where the period character is used for the decimal point:
export LC_NUMERIC=en_US.UTF-8
watch -n 0.1 w
A couple of references:
- A relevant portion of the Linux manpage for
strtod
:
A decimal number consists of a nonempty sequence of decimal digits possibly containing a radix character (decimal point, locale-dependent, usually '.')
You can review your current settings by running
locale
in your terminal:locale LANG=en_US.UTF-8 LC_CTYPE="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_COLLATE="en_US.UTF-8" LC_MONETARY="en_US.UTF-8" ...
The source code in question can be reviewed at gitlab:
https://gitlab.com/procps-ng/procps/blob/85fff468fa263cdd2ff1c0144579527c32333695/watch.c#L625
https://gitlab.com/procps-ng/procps/blob/85fff468fa263cdd2ff1c0144579527c32333695/lib/strutils.c#L49
(edit 2017-09-07): updated gitlab links
Just a complement to zackse's fine answer.
There are two problems with:
LC_NUMERIC=en_US.UTF-8 watch -n 0.1 w
as a work around for the fact that watch
expect numbers formatted in the user's convention while you expect it to be in the English format.
That doesn't work if
LC_ALL
is set.LC_ALL
overrides all other locale settings includingLC_NUMERIC
. The work around would be to use:LC_ALL=en_US.UTF-8 watch -n 0.1 w
but then it would make the second point below even worse
the command started by
watch
(in this casew
) inherits thatLC_NUMERIC
. So instead of outputting its numbers in a format expected by the user, it will output it in the US English format.
Ideally here, we'd want to tell watch to run w
every tenth of a second (regardless of the user's locale) without affecting the behaviour of the w
command (which should always give an output understandable by the user in his own locale).
With the yash
shell, you can do it with:
watch -n "$((0.1))" w
yash
is one of the 3 Bourne-like shells that support floating point arithmetics (the other ones being zsh
and ksh93
). It's the only one that does internationalisation properly though. zsh
always uses .
as the decimal mark, and ksh93
honours the one from the locale event in its internal syntax.
For yash
, .
is the decimal mark for its arithmetic syntax, but it honours the locale's one upon input/output.
Another trick you can use here is to avoid inputting the decimal mark altogether by using scientific notation:
watch -n 1e-1 w
Or you can query the decimal mark from the locale:
m=$(locale decimal_point)
watch -n "0${m}1" w