Não é possível evocar o comando watch com opção de tempo não inteiro

5

Eu quero iniciar o comando w periodicamente, de acordo com man watch , o menor intervalo de tempo possível é 0,1.

Eu tentei:

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

Quando tento iniciar o comando watch com a opção n como não-inteiro, recebo a mensagem de erro:

watch: failed to parse argument: '0.1'
    
por Abdul Al Hazred 29.03.2015 / 17:50

3 respostas

13

Este é um problema local. watch usa strtod(3) , que é dependente de código de idioma, para converter o argumento em -n em double .

Para corrigir o problema, você precisa especificar o argumento para -n com um separador diferente:

watch -n 0,1 w

Ou altere sua localidade para uma configuração em que o caractere de período é usado para o ponto decimal:

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


Algumas referências:

  1. Uma parte relevante da página de manual do Linux para strtod :

A decimal number consists of a nonempty sequence of decimal digits possibly containing a radix character (decimal point, locale-dependent, usually '.')

  1. Você pode revisar suas configurações atuais executando locale em seu 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"
    ...
    
  2. O código-fonte em questão pode ser revisado no gitlab:

    link

    link

(edit 2017-09-07): links atualizados do gitlab

    
por 31.03.2015 / 17:24
2

Apenas um complemento da boa resposta do zackse .

Existem dois problemas com:

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

como uma solução para o fato de que watch espera números formatados na convenção do usuário enquanto você espera que ele esteja no formato inglês.

  1. Isso não funciona se LC_ALL estiver definido. LC_ALL substitui todas as outras configurações de localidade, incluindo LC_NUMERIC . O trabalho seria usar:

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

    mas depois faria o segundo ponto abaixo ainda pior

  2. o comando iniciado por watch (neste caso w ) herda esse LC_NUMERIC . Portanto, em vez de exibir seus números em um formato esperado pelo usuário, ele será exibido no formato em inglês dos EUA.

Idealmente, gostaríamos de dizer ao watch para executar w a cada décimo de segundo (independentemente da localidade do usuário) sem afetar o comportamento do comando w (que deve sempre fornecer uma saída compreensível pelo comando usuário em sua própria localidade).

Com o shell yash , você pode fazer isso com:

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

yash é um dos 3 shells do tipo Bourne que suportam aritmética de ponto flutuante (os outros são zsh e ksh93 ). É o único que faz a internacionalização corretamente embora. zsh sempre usa . como a marca decimal, e ksh93 honra aquela do evento local em sua sintaxe interna.

Para yash , . é a marca decimal da sua sintaxe aritmética, mas ela respeita a localidade na entrada / saída.

Outro truque que você pode usar aqui é evitar a entrada da marca decimal usando notação científica:

watch -n 1e-1 w

Ou você pode consultar a marca decimal da localidade:

m=$(locale decimal_point)
watch -n "0${m}1" w
    
por 24.02.2017 / 23:07
1

Os comandos watch e w não têm nada a ver um com o outro que não seja a primeira letra sendo igual. Você não pode presumir que um parâmetro para w seja igualmente válido para watch . O comando watch leva um número inteiro de segundos como o valor para -n .

A propósito, eu também olhou para a página homem para w e eu não posso ver qualquer referência a um período de tempo. Estou curioso para saber de onde você conseguiu essa informação para que eu possa (espero) explicar melhor.

UPDATE

Aparentemente, você está se referindo ao timer para watch , não para w . Atualizarei sua pergunta para corresponder a essa nova divulgação. Tendo finalmente descoberto isso, não consigo ver nada de errado com watch -n 0.1 w .

    
por 29.03.2015 / 18:09