Repita o comando automaticamente no Linux

303

É possível na linha de comando do Linux repetir um comando a cada n segundos?

Digamos, eu tenho uma importação em execução e estou fazendo

ls -l

para verificar se o tamanho do arquivo está aumentando. Eu gostaria de ter um comando para repetir isso automaticamente.

Marty Wallace
fonte

Respostas:

541

Assista a cada 5 segundos ...

watch -n 5 ls -l

Se você deseja ter confirmação visual das alterações, acrescente --differencesantes do lscomando.

De acordo com a página do manual OSX, também há

A opção --cumulative torna o destaque "pegajoso", apresentando uma exibição contínua de todas as posições que já foram alteradas. A opção -t ou --no-title desativa o cabeçalho, mostrando o intervalo, o comando e a hora atual na parte superior da tela, bem como a seguinte linha em branco.

A página do manual Linux / Unix pode ser encontrada aqui

Rawkode
fonte
4
Nice - pitty sobre isso não anexando resultados para a linha de comando
Marty Wallace
1
Adicionado opção para resposta que permite destacar as alterações
Rawkode
3
Observe que você precisa escapar de caracteres especiais que fazem parte do comando que está assistindo, por exemplo: watch mysql dbname -e \"show processlist\;\"
pfrenssen
11
brew install watch
precisa
1
relógio não está instalado no Mac OS X 10.10
João Nunes
118
while true; do
    sleep 5
    ls -l
done
Oleksandr Kravchuk
fonte
10
watchtambém tem o efeito colateral infeliz de limpar a tela; portanto, às vezes o loop é útil. Qual usar depende do formato desejado da saída.
precisa
Normalmente, eu faço o loop, mas em uma linha. Assista parece muito melhor, no entanto, vou ter que mudar para isso.
Don Branson #:
1
@MartyWallace Isso pode ser feito com a linha de comando (o loop while).
Keyser
Pena de notar que você pode usar --differencespara tê-los realçado (Se você está preocupado com o redesenho do terminal)
Rawkode
Isto é melhor que watch. O Watch não funciona, por exemplo, quando você deseja gerar um número aleatório em cada chamada, por exemplo watch -n 1 echo ${RANDOM}. O aleatório será chamado apenas uma vez.
Marcin
92

"watch" não permite frações de segundo no Busybox, enquanto "sleep" permite. Se isso lhe interessa, tente o seguinte:

while true; do ls -l; sleep .5; done
Mikhail
fonte
1
Isso é útil para se você precisa canalizar a algum lugar de saída (como recursiva bar aint)
Stephen Smith
1
Obrigado. Isso funciona para consoles do busybox que não possuem o comando watch. Usei-o para medir o tempo de atividade do meu sistema: enquanto verdadeiro; faça tempo de atividade; dormir 1; feito
Santiago Villafuerte
FWIW na versão antiga do busybox (v1.11.2), estou preso, não há relógio e o sono não suporta frações. Mas você pode usar o sono 1 com êxito.
Moodboom 23/05
Esta é também uma ótima maneira de executar isso em cygwin
Bradley
34

sleepjá retorna 0. Como tal, estou usando:

while sleep 3 ; do ls -l ; done

Isso é um pouco menor que a solução de mikhail. Uma desvantagem menor é que ele dorme antes de executar o comando target pela primeira vez.

Sebastian Wagner
fonte
18

Se o comando contiver alguns caracteres especiais, como pipes e aspas, o comando precisará ser preenchido com aspas. Por exemplo, para repetir ls -l | grep "txt", o comando watch deve ser:

watch -n 5 'ls -l | grep "txt"'

jonathanzh
fonte
Eu estava tendo problemas para obter o relógio para funcionar corretamente em uma expressão canalizado, mas depois de ler isso, eu poderia corrigi-lo :)
Elysium devorado
13

Executar comandos periodicamente sem cron é possível quando seguimos while.

Como um comando:

while true ; do command ; sleep 100 ; done &
[ ex: # while true;  do echo `date` ; sleep 2 ; done & ]

Exemplo:

while true
do echo "Hello World"
sleep 100
done &

Não esqueça o último, &pois ele colocará seu loop em segundo plano. Mas você precisa encontrar o ID do processo com o comando "ps -ef | grep your_script" e depois matá-lo. Portanto, adicione o '&' ao executar o script.

# ./while_check.sh &

Aqui está o mesmo loop de um script. Crie o arquivo "while_check.sh" e coloque-o:

#!/bin/bash
while true; do 
    echo "Hello World" # Substitute this line for whatever command you want.
    sleep 100
done

Em seguida, execute-o digitando bash ./while_check.sh &

Ranjithkumar T
fonte
O último & não é o mesmo que escrever o comando sem & no final, mas chamar o script com &: bash ./ while_check.sh &?
ransh
@ransh: Podemos executar o script ./ while_check.sh e para obter o ID do processo imediatamente, quando adicionamos o script & in e apenas executamos o script sem &, não obtivemos nenhum ID do processo, mas ele será executado background, como editei, precisamos do comando ps para obter a identificação do processo, se precisarmos parar o script.
Ranjithkumar t
Se desejar, você pode modificar o script para echo $!depois que cada processo em segundo plano for iniciado - esse é o PID do último processo filho iniciado em segundo plano.
Jonathan Leffler
echo `date` é apenas uma maneira pobre e ligeiramente incorreta de escrever apenas date. (O bug tem a ver com a falta de citação do argumento para echo.) Veja também o uso inútil de echo.
Tripleee
7

o relógio é bom, mas limpa a tela.

watch -n 1 'ps aux | grep php'
Eduardo
fonte
6

Se você quiser evitar "desviar", o que significa que você deseja que o comando execute a cada N segundos, independentemente do tempo que leva (supondo que leve menos de N segundos), aqui está uma lista que repetirá um comando a cada 5 segundos com um segunda precisão (e imprimirá um aviso se não conseguir acompanhar):

PERIOD=5

while [ 1 ]
do
    let lastup=`date +%s`
    # do command
    let diff=`date +%s`-$lastup
    if [ "$diff" -lt "$PERIOD" ]
    then
        sleep $(($PERIOD-$diff))
    elif [ "$diff" -gt "$PERIOD" ]
    then
        echo "Command took longer than iteration period of $PERIOD seconds!"
    fi
done

Ainda pode demorar um pouco, pois o sono é preciso apenas por um segundo. Você pode melhorar essa precisão usando o comando date com criatividade.

mcote
fonte
Obrigado .. mas eu tenho 2 perguntas, 1 - onde salvar esse código? em outras palavras, em qual caminho devo colocar o arquivo que contém esse script? que faz funcionar automaticamente ?! 2- como incluir o arquivo php (# do command) em vez de digitar todo o meu código lá?
Hossam
1
Sugiro que você pesquise um pouco sobre scripts bash para entender os conceitos básicos de como executá-los e assim por diante.
Mcote
4

Se você quiser fazer algo um número específico de vezes, sempre poderá fazer isso:

repeat 300 do my first command here && sleep 1.5
bola brilhante
fonte
8
para for x in {1..300} ; do comandos bash do||break;sleep 1.5; done
Jasen 2/16
4

Você pode executar o seguinte e filtrar apenas o tamanho. Se seu arquivo foi chamado, somefilenamevocê pode fazer o seguinte

while :; do ls -lh | awk '/some*/{print $5}'; sleep 5; done

Uma das muitas idéias.

Valentin Bajrami
fonte
2

Para minimizar a deriva mais facilmente, use:

while :; do sleep 1m & some-command; wait; done

ainda haverá uma pequena quantidade de desvio devido ao tempo do bash para executar a estrutura do loop e ao comando sleep para realmente ser executado.

dica: ':' evals para 0 ou seja, verdadeiro.

matemática
fonte
1
watch -n 5 'ls -l 

Executar ls -lcomando após cada 5s

Resultado :-

Every 5.0s: ls -l                                                                                                      Fri Nov 17 16:28:25 2017

total 169548
-rw-rw-r--  1 sachin sachin     4292 Oct 18 12:16 About_us_Admission.doc
-rw-rw-r--  1 sachin sachin      865 Oct 13 15:26 About_us_At_glance.doc
-rw-rw-r--  1 sachin sachin     1816 Oct 13 16:11 About_us_Principle.doc
-rw-rw-r--  1 sachin sachin     1775 Oct 13 15:59 About_us_Vission_mission.doc
-rw-rw-r--  1 sachin sachin     1970 Oct 13 16:41 Academic_Middle_school.doc
-rw-rw-r--  1 sachin sachin      772 Oct 16 16:07 academics_High_School.doc
-rw-rw-r--  1 sachin sachin      648 Oct 16 13:34 academics_pre_primary.doc
-rw-rw-r--  1 sachin sachin      708 Oct 16 13:39 academics_primary.doc
-rwxrwxr-x  1 sachin sachin     8816 Nov  1 12:10 a.out
-rw-rw-r--  1 sachin sachin    23956 Oct 23 18:14 Ass1.c++
-rw-rw-r--  1 sachin sachin      342 Oct 23 22:13 Ass2.doc
drwxrwxr-x  2 sachin sachin     4096 Oct 19 10:45 Backtracking
drwxrwxr-x  3 sachin sachin     4096 Sep 23 20:09 BeautifulSoup
drwxrwxr-x  2 sachin sachin     4096 Nov  2 00:18 CL_1
drwxrwxr-x  2 sachin sachin     4096 Oct 23 20:16 Code
drwxr-xr-x  2 sachin sachin     4096 Nov 15 12:05 Desktop
-rw-rw-r--  1 sachin sachin        0 Oct 13 23:12 doc
drwxr-xr-x  4 sachin sachin     4096 Nov  6 21:18 Documents
drwxr-xr-x 27 sachin sachin    12288 Nov 17 13:23 Downloads
-rw-r--r--  1 sachin sachin     8980 Sep 19 23:58 examples.desktop
HeadAndTail
fonte
1

Uma solução concisa, que é particularmente útil se você deseja executar o comando repetidamente até que ele falhe e permite ver toda a saída.

while ls -l; do
    sleep 5
done
arsdragonfly
fonte