shell script para verificar a disponibilidade de um arquivo por 1 hora, após uma hora se o arquivo não estiver lá, ele irá ecoar "Time Out"

shell script para verificar a disponibilidade de um arquivo por 1 hora, após uma hora se o arquivo não estiver lá, ele irá ecoar "Time Out"

eu escrevi esse código. mas o problema é que a cada 300 segundos ele imprime "Time over", quando $fname present sai do loop. Quero "fim de tempo" após 1 hora se o arquivo não chegar, mas depois de 300 ele começa a imprimir "fim de tempo"

echo "enter file name"

read fname

START=`date +%s`
while [ $(( $(date +%s) - 3600 )) -lt $START ]; do
  if [ -e $fname ]
  then
    echo "$fname present"
    break
    sleep 300
  else
    echo "Time Over"
  fi
done

Responder1

Acho que você já está perto, mas alguns aspectos do seu roteiro parecem complicados demais.

Você poderia tentar o seguinte whileloop:

#!/bin/sh

timeout=3600
granularity=300
elapsed=0

echo "Please enter the filename"
read -r file

while [ "$elapsed" -lt "$timeout" ]
do
    if [ -f "$file" ]
    then
        break
    fi

    sleep "$granularity"
    elapsed=$((elapsed+granularity))
done

# Was the loop broken because the file appeared, or did it time out?
if [ -f "$file" ]
then
    echo "$file has appeared"
else
    echo "Time over"
fi

Isto irá verificar a cada $granularitysegundo se o arquivo está presente, até que o $timeoutvalor seja excedido. Se o arquivo aparecer, o script sairá do loop.

O problema com sua abordagem foi que a saída "Time over" está no elseramo da sua verificação periódica e, portanto, ocorrerátoda vez que o loop é iteradose o arquivo não foi encontrado. Em vez disso, sugiro verificardepois do ciclose a sua variável de teste (no seu script a saída de date) excedeu o limite (indica que o loop expirou) ou, alternativamente (talvez ainda melhor) se o arquivo estiver presente, para decidir se deseja ou não gerar a mensagem "Tempo esgotado" .

Responder2

Uma abordagem alternativa, que evita as desvantagens da votação (o compromisso entre o consumo de recursos para ciclos curtos de votação e o atraso na detecção de alterações para ciclos longos de votação). O preço a pagar é que depende de ferramentas que podem não estar disponíveis para você, nomeadamenteferramentas inotifyetimeout(este último deGNU Coreutils).

fnameSupondo que o significado de "verificar a disponibilidade" é que você está aguardando a criação de um arquivo (cujo nome está na variável):

timeout 3600 sh -c '
    if [ -e "$1" ]; then
        printf "%s is present already\n" "$1"
        exit
    fi
    while inotifywait -qq -e create dir; do
    if [ -e "$1" ]; then
        printf "%s present\n" "$1"
        exit
    fi
done' mysh "$fname"
[ "$?" -eq 124 ] && echo "Time over"

timeoutexecuta um comando pela duração especificada, que aqui é 3600segundos ( sé a unidade de tempo padrão). Se o tempo limite for atingido, timeoutsai com o status 124; caso contrário, ele sai com o status do comando que está executando.

inotifywaitaguarda alterações no dirdiretório (aquele em que $fnamedeve ser criado); createé o evento que estamos observando; -qqfaz com que seja realmente bastante.

Este tipo de verificação às vezes é implementado (por exemplo, em outras perguntas e respostas neste site) como:

inotifywait -m ... --format "%f" | while read -r file; do ...

onde -m(modo monitor) impede inotifywaita saída após o primeiro evento correspondente e o lado direito do canal recebe o nome do arquivo do qual o evento se tratava. Infelizmente, essa abordagem falha se os nomes dos arquivos contiverem <newline>s.

É por isso que, no código mostrado acima, não usamos -me verificamos a existência de $fnameduas vezes. Esta abordagem é um pouco frágil porque$fname poderser criado entre a primeira [ -e "$1" ]e a primeira execução inotifywait(e entre as execuções inotifywaittambém). Também não é muito adequado caso muitos arquivos tenham sido criados no diretório monitorado, porque cada execução inotifywaitconfigura seus próprios relógios.

Responder3

O script a seguir lê FILENAMEenquanto verifica a entrada vazia, calcula END_DATEusando o datecomando, certificando-se de que o tempo de uma hora do relógio não seja excedido e verifica se um arquivo nomeado FILENAMEexiste a cada INTERVALsegundo. No caso da data atual:

  • é igual a END_DATE: uma última verificação de existência de arquivo ocorre com o script saindo do loop while logo após (sem espera de 300 segundos).
  • excede END_DATE: o loop while é interrompido sem verificar a existência do arquivo.
#!/usr/bin/env bash

echo -n "Enter file name to monitor: "

read FILENAME

if [ -z "${FILENAME}" ]
then
    echo -e "\nError: Filename is empty!\nExiting..."
    exit 1
fi

END_DATE=$(date --date='next hour' '+%s')
INTERVAL=300

FOUND="false"
while :
do
    CURRENT_DATE="$(date '+%s')"
    if [ "${CURRENT_DATE}" -gt "${END_DATE}" ]
    then
        break
    elif [ "${CURRENT_DATE}" -eq "${END_DATE}" ]
    then
        INTERVAL='0.1'   # Allow for one last check
    fi

    if [ -e "${FILENAME}" ]
    then
        FOUND="true"
        break
    fi
    sleep "${INTERVAL}"
done

if [ "${FOUND}" == "true" ]
then
    echo "${FILENAME} is present"
else
    echo "Time is Over"
fi

informação relacionada