Calcula o tempo decorrido de cada comando em tempo real como um cronômetro [fechado]

1

Eu tenho um script para fazer muitas coisas, por exemplo:

echo -e " finding mp3 files"
find / *.mp3
Elapsed time: 0

Suponha que isso demore 10 segundos.

Uma função para copiá-los para algum local (isso é apenas um exemplo, não meu script real):

echo copying files;
cp *.mp3 /
elapsed time: 6

Eu preciso de uma maneira de calcular e mostrar um relógio em execução enquanto find encontra todos os arquivos e depois disso para redefinir e mostrar um novo relógio em execução enquanto cp copia os arquivos.

Eu tentei isso:

Timing () {
SECONDS=0; while true do;
printf '\e[1;96mElapsed Time: %dm:%ds\e[0m\n' $(($SECONDS%3600/60)) $(($SECONDS%60))
done &
}

e, em seguida, chamar esta função ao fazer o comando.

No entanto, não consigo redefinir a hora e não consigo sair desse plano de fundo while loop.

Aqui está o script completo que eu quero adicionar a função de tempo para:

#!/bin/bash

#--------------------------------------------------------------------------------#
#                  Modify to Match your Environment                              #
#--------------------------------------------------------------------------------#

#enter managed servers names  STARTING ORDER  seperated by 'space'
#COMPNENTS Y or N in CAPS litters 

MANAGED_SERVERS_NAMES="WLS_FORMS WLS_REPORTS"
NODEMANAGER_SCRIPT_LOCATION="$WLS_HOME"/server/bin/startNodeManager.sh 
DOMAIN_ENV_LOCATION="$DOMAIN_HOME"/bin/setDomainEnv.sh
ADMINSERVER_SCRIPT_LOCATION="$DOMAIN_HOME"/bin/startWebLogic.sh
MANAGED_SERVERS_SCRIP_LOCATION="$DOMAIN_HOME"/bin/startManagedWebLogic.sh
OPMNCTL_COMPONENTS=Y
EMCTL_COMPONENT=Y


################################################################################
#--------------------------------------------------------------------------------#
#           This Script Is A CopyRight To KhaLiD Abo EL MaGd                     #
#                  Don't Modify Any Thing in This Section                        #
#                                                                                #
#--------------------------------------------------------------------------------#
set -e
clear
TFILE=starting.log
debug=$1
if [[ -n "$debug" ]]; then
cat /dev/null > ${TFILE}
gnome-terminal  -e  "tail -F $TFILE" &
fi

Check_Status_NM ()
{
tail -f ${TFILE} | while read LOGLINE
do
    if [[ "${LOGLINE}" == *"Secure socket listener started on port"* ]] 
    then
    echo -e "\e[92mNodeManager Started\e[0m"
    pkill -P $$ tail
    break
    elif [[ "${LOGLINE}" == *"Address already in use"*  ]]; then
    pkill -P $$ tail
    echo -e "Cannot Start NodeManager\nSee ${TFILE} for more info\n "
  printf '\e[1;96mElapsed Time: %dm:%ds\e[0m\n' $(($SECONDS%3600/60)) $(($SECONDS%60))
  echo ""
  echo "$SECONDS" > time
    exit 1
    nohup kill -9 'ps -ef | grep ${TFILE} | awk '{print $2}''  > /dev/null 2>&1 &
    echo "Total Time: $(cat time |   paste -sd+ |  bc)s"
    rm -rf time
    fi
done
}
#----------------------------------------------------------------
Check_Status ()
{
sleep 2
tail -F ${TFILE} | while read LOGLINE
do
  if [[ "${LOGLINE}" == *"<Server state changed to STANDBY>"* ]]; then
    echo -e "\e[94mServer state changed to STANDBY\e[0m"
  elif  [[ "${LOGLINE}" == *"<Server state changed to >"* ]]; then
      echo -e "\e[94mServer state changed to ADMIN\e[0m"
  elif [[ "${LOGLINE}" == *"<Server state changed to RESUMING>"* ]]; then
     echo -e "\e[94mServer state changed to RESUMING\e[0m"
  elif  [[ "${LOGLINE}" == *"<Server state changed to STARTING>"* ]]; then
      echo -e "\e[94mServer state changed to STARTING\e[0m"


    elif [[ "${LOGLINE}" == *"The Network Adapter could not establish the connection"* ]] ; then
    echo -e "\e[5m\e[93mWARNING\e[0m Could not establish the connection\n\e[91mCheck Connection to Database\e[0m"
   elif  [[ "${LOGLINE}" == *"<Server state changed to STARTING>"* ]]; then
      echo -e "\e[94mServer state changed to RUNNING\e[0m"
    elif [[ "${LOGLINE}" == *"<Server started in RUNNING mode>"* ]] || [[ "${LOGLINE}" == *"<Demo trusted CA certificate is being used in production mode:"* ]];then
    echo -e "\e[92mServer Started\e[0m"
      pkill -P $$ tail
    cat /dev/null > ${TFILE}
    break
    elif [[ "${LOGLINE}" == *"<Server state changed to FORCE_SHUTTING_DOWN>"* ]]; then
      pkill -P $$ tail
     echo -e "\e[91mCannot Start Server\e[0m\nSee ${TFILE} for more info\n"
    printf '\e[1;96mElapsed Time: %dm:%ds\e[0m\n' $(($SECONDS%3600/60)) $(($SECONDS%60))
    echo ""
   echo "$SECONDS" >> time
    nohup kill -9 'ps -ef | grep ${TFILE} | awk '{print $2}''  > /dev/null 2>&1 &
    echo "Total Time: $(cat time |   paste -sd+ |  bc)s"
    rm -rf time
    exit 1
    fi
done
}
#---------------------------------------------------------------------------------------
#Start NodeManager:
SECONDS=0
echo -e "Starting NodeManager..."
nohup "$NODEMANAGER_SCRIPT_LOCATION"  > ${TFILE}  2>&1 &
 Timing ******************
Check_Status_NM
printf '\e[1;96mElapsed Time: %dm:%ds\e[0m\n' $(($SECONDS%3600/60)) $(($SECONDS%60))
echo ""
echo "$SECONDS" >> time
#Start WebLogic AdminServer------------------------------------------------
SECONDS=0
echo -e "Starting AdminServer..." 
nohup "$DOMAIN_ENV_LOCATION" > ${TFILE}   2> /dev/null &
 Timing ********************
nohup  > ${TFILE} "$ADMINSERVER_SCRIPT_LOCATION"  2> /dev/null &
Check_Status
printf '\e[1;96mElapsed Time: %dm:%ds\e[0m\n' $(($SECONDS%3600/60)) $(($SECONDS%60))
echo ""
echo "$SECONDS" >> time
#----------- MANAGED SERVERS------------------------------
for i in ${MANAGED_SERVERS_NAMES}
do
SECONDS=0
echo "Starting $i Server..."
nohup ${MANAGED_SERVERS_SCRIP_LOCATION} $i  > ${TFILE}  2> /dev/null &
Check_Status
printf '\e[1;96mElapsed Time: %dm:%ds\e[0m\n' $(($SECONDS%3600/60)) $(($SECONDS%60))
echo ""
echo "$SECONDS" >> time
done
nohup kill -9 'ps -ef | grep ${TFILE} | awk '{print $2}''  > /dev/null 2>&1 &

#--------------------- OPMNCTL------------------------
if [[ "${OPMNCTL_COMPONENTS}" == *"Y"* ]]; then
SECONDS=0
echo -e "Starting opmn components"
nohup opmnctl startall > /dev/null 2>&1 &
sleep 2
if ( opmnctl status |grep --quiet Init); then
echo -e "\e[94mWaiting For opmn components to Start\e[0m"
opmnctl status |grep -v --quiet Init
opm_pid=$!
while [ -d /proc/$opm_pid ]; do
    echo -n "."
    sleep 2
done
else
echo -e "\e[92mStarted\e[0m" 
fi
opmnctl status | grep -v Alive
printf '\e[1;96mElapsed Time: %dm:%ds\e[0m\n' $(($SECONDS%3600/60)) $(($SECONDS%60))
echo ""
echo "$SECONDS" >> time
fi
#---------------------EMCTL-----------------------------------
if [[ "${EMCTL_COMPONENT}" == *"Y"* ]]; then
SECONDS=0
emctl start agent
printf '\e[1;96mElapsed Time: %dm:%ds\e[0m\n' $(($SECONDS%3600/60)) $(($SECONDS%60))
echo ""
echo "$SECONDS" >> time
fi
#-----------------------------------------------------------
TIMEE=$(cat time |   paste -sd+ |  bc)
echo ""
printf '\e[1;96mTotal Time: %dm:%ds\e[0m\n'  $(($TIMEE%3600/60)) $(($TIMEE%60))
cat /dev/null > time
exit 0

eu consegui principalmente obter o que eu quero fazendo isso com base nas respostas mas eu quero saber como matar o loop while na função Check_Status depois que ele imprime servidor iniciado ou não é possível iniciar o servidor

echo -e "Starting AdminServer..." 
nohup "$DOMAIN_ENV_LOCATION" > ${TFILE}   2> /dev/null &
START_TIME=$(date +%s)
nohup  > ${TFILE} "$ADMINSERVER_SCRIPT_LOCATION"  2> /dev/null &
Check_Status &
while [[ -d /proc/$! ]]; do
SECONDS=$(( $(date +%s)-START_TIME ))
 printf "\e[1;96mElapsed Time: %02dm:%02ds\e[0m\r" $(($SECONDS%3600/60))     $(($SECONDS%60))
done
printf "\e[1;96mElapsed Time: %dm:%ds\e[0m\n" $(($SECONDS%3600/60))    $(($SECONDS%60))
echo "$SECONDS" >> time
    
por Khalid Abo El MaGd 23.08.2016 / 21:07

2 respostas

2

Este mostra o momento em que é feito:

#! /bin/bash
START_TIME=$(date +%s)
echo -n Finding mp3 files
sleep 3 # some time consuming command
echo .\ Elapsed time: $(( $(date +%s)-START_TIME ))

Ele responderá:

Finding mp3 files

e depois

Finding mp3 files. Elapsed time: 3

Se você quiser ver o tempo contando enquanto espera, o comando demorado não deve ecoar nada (é claro).

#! /bin/bash
START_TIME=$( date +%s )
echo Finding mp3 files
sleep 3 & # some time consuming command
while [[ -d /proc/$! ]]; do
    echo -en \rElapsed time: $(( $(date +%s)-START_TIME ))
    sleep 0.1
done
echo .

Explicação: Quando o comando entra em segundo plano com & , ele deixa o número de identificação do processo em $! . Esse processo é representado por um diretório (virtual) em /proc/$! . Enquanto esse diretório existir, o comando está em execução e estamos contando o tempo.

Terceiro exemplo; mais parecido com a pergunta. Substitua sleep 3 pelo comando demorado.

#! /bin/bash
echo "Starting NodeManager..."
START_TIME=$(date +%s)
nohup sleep 3 &
while ps -p $! > /dev/null ; do
    SECONDS=$(( $(date +%s)-START_TIME ))
    printf "\r\e[1;96mElapsed Time: %02dm:%02ds\e[0m" $(($SECONDS%3600/60)) $(($SECONDS%60))
done
Echo

Editar: o terceiro exemplo agora mostra o caminho certo para testar um processo ainda está em execução. (mas tem que lançar um processo ps e assim é mais lento - a sua escolha)

    
por 23.08.2016 / 22:50
1

Você pode usar pv :

sleep 10 | pv -t

find / -name '*.mp3' | pv -t

pv é uma passagem como cat (às vezes até mais eficiente, pois usa chamadas de sistema como splice() , quando possível), que escreve as informações de tempo em stderr.

Se você quiser exibir Elapsed time: também:

pv -N 'Elapsed time' -t

ou (com versões mais recentes):

pv -F 'Elapsed time: %t'

Se estiver usando zsh , ksh ou bash , talvez queira definir a opção pipefail para não perder o status de saída do comando que está sendo monitorado:

timewatch() (
  set -o pipefail
  "$@" | pv -tN 'Elapsed time'
)

timewatch find / -name '*.mp3' || handle_error
    
por 24.08.2016 / 11:08

Tags