无法使用非整数时间选项调用 watch 命令

无法使用非整数时间选项调用 watch 命令

我想w周期性地启动命令,按照man watch最小可能的时间间隔是0.1。

我试过:

watch -n1 w        (works)
watch -n1.5 w      (does not work)
watch -n0.1 w      (does not work)

当我尝试watch使用 n 选项作为非整数启动命令时,我收到错误消息:

watch: failed to parse argument: '0.1'

答案1

这是一个区域设置问题。watch使用strtod(3)与语言环境相关的 来将参数 转换-ndouble

要解决此问题,您需要-n使用不同的分隔符指定参数:

watch -n 0,1 w

或者将您的区域设置更改为使用句点字符作为小数点的设置:

export LC_NUMERIC=en_US.UTF-8
watch -n 0.1 w


一些参考资料:

  1. Linux 联机帮助页的相关部分strtod

十进制数由非空的十进制数字序列组成,可能包含基数字符(小数点,取决于区域设置,通常为“.”)

  1. locale您可以通过在终端中运行来查看当前设置:

    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"
    ...
    
  2. 有问题的源代码可以在 gitlab 上查看:

    https://gitlab.com/procps-ng/procps/blob/85fff468fa263cdd2ff1c0144579527c32333695/watch.c#L625

    https://gitlab.com/procps-ng/procps/blob/85fff468fa263cdd2ff1c0144579527c32333695/lib/strutils.c#L49

(编辑2017-09-07):更新了gitlab链接

答案2

只是一个补充扎克斯的好答案

有两个问题:

LC_NUMERIC=en_US.UTF-8 watch -n 0.1 w

作为一种解决方法,因为您watch希望数字按照用户约定格式化,而您希望它采用英语格式。

  1. LC_ALL如果设置了则不起作用。LC_ALL覆盖所有其他区域设置,包括LC_NUMERIC.解决方法是使用:

    LC_ALL=en_US.UTF-8 watch -n 0.1 w
    

    但这样会使下面的第二点变得更糟

  2. watch由(在本例中w)启动的命令继承了该命令LC_NUMERIC。因此,它不会以用户期望的格式输出其数字,而是以美国英语格式输出。

理想情况下,我们希望告诉 watchw每十分之一秒运行一次(无论用户的区域设置如何),而不影响命令的行为w(它应该始终给出用户在其自己的区域设置中可以理解的输出)。

使用yashshell,您可以执行以下操作:

 watch -n "$((0.1))" w

yash是 3 个支持浮点运算的类 Bourne shell 之一(其他的是zshksh93)。但它是唯一能够正确进行国际化的一个。zsh始终用作.小数点,并ksh93在其内部语法中遵循区域设置事件中的小数点。

对于yash,.是其算术语法的小数点,但它在输入/输出时遵循语言环境的小数点。

您可以在此处使用的另一个技巧是使用科学记数法来避免完全输入小数点:

watch -n 1e-1 w

或者您可以从语言环境中查询小数点:

m=$(locale decimal_point)
watch -n "0${m}1" w

答案3

除了第一个字母相同之外,命令watchw彼此无关。您不能假设 的参数w对于 同样有效watch。该watch命令采用整数秒作为 的值-n

顺便说一句,我也看过手册页w我看不到任何对时间段的提及。我很想知道您从哪里获得此信息,以便我可以(希望)进一步解释。

更新

看来您实际上指的是计时器 for watch,而不是 for w。我将更新您的问题以匹配此新披露。终于发现了这一点,我看不出有什么问题watch -n 0.1 w

相关内容