web-dev-qa-db-ja.com

整数以外の時間オプションで監視コマンドを呼び出すことはできません

man watchに従って、wコマンドを定期的に開始したいのですが、可能な最小の時間間隔は0.1です。

私は試した:

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

Nオプションを非整数としてwatchコマンドを開始しようとすると、次のエラーメッセージが表示されます。

watch: failed to parse argument: '0.1'
6
Abdul Al Hazred

これはロケールの問題です。 watchは、ロケールに依存するstrtod(3)を使用して、引数を-nからdoubleに変換します。

この問題を解決するには、-nの引数を別の区切り文字で指定する必要があります。

watch -n 0,1 w

または、ロケールを小数点にピリオド文字が使用される設定に変更します。

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


いくつかの参考資料:

  1. strtodのLinuxマンページの関連部分:

10進数は、基数文字(小数点、ロケール依存、通常は「。」)を含む可能性のある空でない10進数のシーケンスで構成されます。

  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リンク

14
zackse

zackseのすばらしい答え を補完するだけです。

次の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番目のポイントをさらに悪化させるでしょう

  2. watch(この場合はw)で開始されたコマンドは、そのLC_NUMERICを継承します。そのため、ユーザーが期待する形式で数値を出力する代わりに、米国英語形式で出力します。

ここでは、理想的には、wコマンドの動作に影響を与えずに(ユーザーのロケールに関係なく)10分の1秒ごとにwを実行するようにwatchに指示したいと思います(常に出力を提供する必要があります)ユーザーが自分のロケールで理解できる)。

yashシェルを使用すると、次の方法で実行できます。

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

yashは、浮動小数点演算をサポートする3つのBourneのようなシェルの1つです(他のシェルはzshksh93です)。ただし、国際化を適切に行うのはこれだけです。 zshは常に小数点として.を使用し、ksh93は内部構文でロケールイベントからのものを尊重します。

yashの場合、.は算術構文の小数点ですが、入出力時にロケールの小数点を尊重します。

ここで使用できるもう1つのトリックは、科学的記数法を使用して小数点を完全に入力しないようにすることです。

watch -n 1e-1 w

または、ロケールから小数点を照会できます。

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

コマンドwatchwは、最初の文字が等しいことを除いて、互いに何の関係もありません。 wのパラメータがwatchに対して等しく有効であると想定することはできません。 watchコマンドは、-nの値として整数秒かかります。

ちなみに、 w のマニュアルページも見てきましたが、期間への参照が見当たりません。この情報をどこから入手したのか知りたいので、(願わくば)さらに説明することができます。

更新

実際には、watchではなく、wのタイマーを参照しているようです。この新しい開示に一致するように質問を更新します。ついにこれを発見しましたが、watch -n 0.1 wに問題はありません。

1
roaima