Para ficar um pouco mais perto do código original, o que eu faço é:
while true; do
sleep 1 &
...your stuff here...
wait # for sleep
done
Isso muda um pouco a semântica: se o seu material levar menos de um segundo, ele simplesmente esperará passar o segundo inteiro. No entanto, se o seu material demorar mais de um segundo por qualquer motivo, ele não continuará gerando ainda mais subprocessos sem nunca ter fim.
Assim, suas coisas nunca são executadas em paralelo, e não em segundo plano, então as variáveis funcionam como o esperado.
Observe que, se você iniciar tarefas adicionais em segundo plano, terá que alterar a instrução wait
para aguardar apenas o processo sleep
especificamente.
Se você precisar que ele seja ainda mais preciso, você provavelmente só precisará sincronizá-lo com o clock do sistema e dormir ms em vez de segundos completos.
Como sincronizar com o relógio do sistema? Nenhuma ideia, tentativa estúpida:
Padrão:
while sleep 1
do
date +%N
done
Saída: 003511461 010510925 016081282 021643477 028504349 03 ... (continua crescendo)
sincronizado:
while sleep 0.$((1999999999 - 1$(date +%N)))
do
date +%N
done
Saída: 002648691 001098397 002514348 001293023 001679137 00 ... (permanece mesmo)