Existem algumas coisas técnicas erradas com o seu script / abordagem, mas esquecendo os detalhes técnicos por um momento, em um nível intuitivo, o que você está tentando fazer é colocar algum processo de contagem em movimento, então em algum momento no futuro - você quer interativamente consultar o processo para ver como as coisas estão indo tentando referenciar diretamente o valor da variável.
Você não pode fazer isso no bash porque o bash shell é um interpretador de linguagem síncrono , o que significa que enquanto o processo bash está executando o loop while
você não pode interrompê-lo e dizer o equivalente de programação :
"hey bash, stop what you are doing, then go off and access some piece of memory (the $SESSIONLENGTH
variable) and then print out its value to screen, then carry on whatever you were doing"
O que você está tentando fazer é resolvido pela simultaneidade e é o tipo de coisa que você faz em assíncrono (nodejs, nginx) plataformas ou processos de encadeamento único executando um loop de eventos como o vim, ou javascript em um navegador da web.
A partir do artigo sobre simultaneidade da Wikipedia
A concurrent system is one where a computation can advance without waiting for all other computations to complete; where more than one computation can advance at the same time
Eu adicionaria o qualificador ou pelo menos apareceria para o usuário como se mais de um cálculo estivesse avançando ao mesmo tempo.
Então, o que você pode fazer em bash? você pode - como foi sugerido, obter o bash para enviar sua saída para outro lugar, ler os dados de um processo separado ou colocar essa versão modificada do seu código em um arquivo:
session_state.sh
for i in seq 1 2 3 4 5
do
SECONDSINSESSION=$SECONDS
SECONDSINMINUTE=60
SECONDSINHOUR=3600
SECONDSINDAY=86400
DAYSINSESSION=$(expr "$SECONDSINSESSION" / "$SECONDSINDAY")
DAY_REMAINDER=$(expr "$SECONDSINSESSION" % "$SECONDSINDAY")
HOURSINSESSION=$(expr "$DAY_REMAINDER" / "$SECONDSINHOUR")
HOUR_REMAINDER=$(expr "$DAY_REMAINDER" % "$SECONDSINHOUR")
MINUTESINSESSION=$(expr "$HOUR_REMAINDER" / "$SECONDSINMINUTE")
SECONDSINSESSION=$(expr "$HOUR_REMAINDER" % "$SECONDSINMINUTE")
SESSIONLENGTH="$DAYSINSESSION days, $HOURSINSESSION hours, $MINUTESINSESSION minutes, and $SECONDSINSESSION seconds."
echo $SESSIONLENGTH
sleep 2
done
, em seguida, fonte:
$ source session_state.sh
0 days, 0 hours, 46 minutes, and 26 seconds.
0 days, 0 hours, 46 minutes, and 28 seconds.
0 days, 0 hours, 46 minutes, and 30 seconds.
0 days, 0 hours, 46 minutes, and 32 seconds.
0 days, 0 hours, 46 minutes, and 34 seconds.
0 days, 0 hours, 46 minutes, and 36 seconds.
, em seguida, consulte a variável
$ echo $SESSIONLENGTH
0 days, 0 hours, 46 minutes, and 36 seconds.
E você obterá a variável como ela existia em seu estado final - mas somente após o término do processo.
Uma solução teórica para o que você queria originalmente, em um shell síncrono de encadeamento único, seria
- crie um segundo processo que monitore sua entrada de teclado,
- tinha algum arranjo pré-estabelecido com o bash, então o segundo processo poderia
-
queue suas solicitações geradas pelo usuário para que, quando bash
- terminou seu quadro / unidade de código atual, seria
- verifique a fila para solicitações do usuário,
- executá-los e, em seguida,
- continue de onde parou pela última vez
em outras palavras, um loop de eventos .