Je veux écrire un script bash pour exécuter un minuteur pendant 30 secondes. Après 30 secondes, il devrait rester enfoncé pendant 30 secondes. Ce minuteur démarrera de nouveau pendant 30 secondes et continuera ainsi.
for ((i=30; i>0; i--)); do
sleep 1 &
print "$i \r"
wait
done
En utilisant le code ci-dessus, je peux exécuter le chronomètre pendant 30 secondes, mais je dois rester en attente pendant les 30 secondes suivantes, puis à nouveau exécuter le chronomètre pour les 30 prochaines secondes.
Comment puis-je faire ceci?
même chose que je peux faire dans Java en utilisant ce code
import Java.util.Timer;
import Java.util.TimerTask;
public class TestClass {
static int count = 0;
public static void main(String[] args) {
final TestClass test = new TestClass();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
test.doStuff();
}
}, 0, 1000);
}
public void doStuff() {
if (count == 30) {
try {
Thread.sleep(30000);
count = 0;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(++count);
}
}
Enroulez votre boucle dans une boucle infinie ( c'est-à-dire une boucle while
sans conditions), et ajoutez un sleep 30
dans cette boucle externe .
while :
do
### < your
### timer
### here >
sleep 30
done
Je vous suggère également de supprimer l'instruction wait
et le &
de "sleep 1 &
". De plus, print
n'est pas le bon programme pour écrire dans le terminal, utilisez plutôt echo
.
while :
do
for ((i=30; i>0; i--))
do
sleep 1
echo -n "$i "
done
sleep 30
echo ""
done
Sachez que cette minuterie n’est pas précise, car l’évaluation des instructions de boucle prend un laps de temps (petit, mais non nul). Une solution utilisant date
serait préférable: voir par exemple la fonction de compte à rebours ici: https://superuser.com/a/611582 .
Je pense que vous cherchez quelque chose comme ça:
#!/bin/bash
## Infinite loop
while :; do
## Run a sleep command for 30 seconds in the background
sleep 30 &
## $! is the PID of the last backgrounded process, so of the sleep.
## Wait for it to finish.
c=30
while [[ -e /proc/$! ]]; do
printf '%s\r' "$(( --c ))"
## For more precision, comment the line below. This causes the
## script to wait for a second so it doesn't spam your CPU.
## If you need accuracy, comment the line out. Although, if you
## really need accuracy, don't use the Shell for this.
sleep 1
done
done
Vous pouvez également utiliser date
:
#!/bin/bash
waitTime=30;
## Infinite loop
while :; do
startTime=$(date +%s)
currentTime=$(date +%s)
c=$waitTime;
while [[ $((currentTime - startTime)) -lt $waitTime ]]; do
printf '%s\r' "$(( --c ))"
## For more precision, comment the line below. This causes the
## script to wait for a second so it doesn't spam your CPU.
## If you need accuracy, comment the line out. Although, if you
## really need accuracy, don't use the Shell for this.
sleep 1
currentTime=$(date +%s)
done
c=0
echo "";
done
Pour encore plus de précision, ne stockez pas la date dans une variable:
#!/bin/bash
waitTime=4;
while :; do
startTime=$(date +%s)
c=$waitTime;
while [[ $(($(date +%s) - startTime)) -lt $waitTime ]]; do
printf '%s\r' "$(( --c ))"
sleep 1
done
c=0
done