O script de contagem decrescente não está funcionando

5

Estou tentando criar um script que contará até 0 de qualquer número que eu fornecer. Abaixo está o meu script e basicamente nada acontece, nenhuma mensagem de erro, eu simplesmente recebo o prompt de linha de comando padrão de volta.

#!/bin/bash
#countdown
#counts down to 0 from whatever number you give it
#displaying a number each second

NUM=${1:-0}
if [ $NUM -gt 0 ]
then
   while [ $NUM -gt 0 ]
   do
      if [ -f /usr/bin/banner ]
      then
         /usr/bin/banner "$NUM"
      else
         echo $NUM
      fi
         NUM=$(($NUM-1))
         sleep 2
   done
fi
    
por HankG 13.04.2015 / 17:27

3 respostas

3
#!/bin/bash

printf "Type an integer number: " && read NUM
if [ $NUM -gt 0 ]
then
   while [ $NUM -ge 0 ]
   do
      if [ -f /usr/bin/banner ]
      then
         /usr/bin/banner "$NUM"
      else
         echo $NUM
      fi
         NUM=$(($NUM-1))
         sleep 2
   done
fi

saída:

:~$ ./countdown.sh 
Type an integer number: 10
10
9
8
7
6
5
4
3
2
1
0

explicação:
⠀1. linha 3 solicita ao usuário inserir um número inteiro e lê-lo na variável NUM.
⠀2. Alterou o -gt na linha 6 para -ge para que seja reduzido a zero.
⠀3. A saída é exibida no formato de banner se o sysvbanner estiver instalado ou então como texto, se não for.

    
por karel 13.04.2015 / 17:40
3

Código aprimorado e comentado:

#!/bin/bash

num=${1:-undefined}                                   # If $1 (the first argument passed to the script) is set, then num=$1, else num=undefined.
cmd=$(which {banner,echo} | head -1 | xargs basename) # If banner is installed, then cmd=baner, else cmd=echo.

until [[ "$num" =~ ^[0-9]+$ ]]; do                    # Until $num become a valid number (loop will not be executed if $1 is set):
    read -p "Type a number: " num                         # Ask the user for a valid number.
done                                                  # End of the until loop.

for ((num;num>=0;num--)); do                          # Loop using $num as variable; while $num is greater or equal than zero; num=$num-1.
   $cmd $num                                              # Runs $cmd (banner or echo) passing $num as argument.
   sleep 1                                                # Stop the program execution for one second.
done                                                  # End of the for loop.

O código acima incluirá zero na contagem regressiva, se você quiser parar quando a contagem regressiva atingir 1 , será necessário fazer apenas algumas alterações:

  1. Na sexta linha, altere ^[0-9]+$ por ^[1-9]+[0-9]*$ para que fique assim:

    until [[ "$num" =~ ^[1-9]+[0-9]*$ ]]; do              # Until $num become a valid number (loop will not be executed if $1 is set):
    
  2. Na linha 10, remova o sinal = para que fique assim (atualizei também o comentário):

    for ((num;num>0;num--)); do                           # Loop using $num as variable; while $num is strictly greater than zero; num=$num-1.
    

Seu programa original não funciona porque:

  • Você não passou um número como argumento para o programa.
  • Um exemplo de chamada desse comando é ./countdown 5 , em que 5 é o número.
  • Se você quer lidar com isso, você pode adicionar um else ao seu código (veja as cinco últimas linhas):

    #!/bin/bash
    #countdown
    #counts down to 0 from whatever number you give it
    #displaying a number each second
    
    NUM=${1:-0}
    if [ $NUM -gt 0 ]
    then
       while [ $NUM -gt 0 ]
       do
          if [ -f /usr/bin/banner ]
          then
             /usr/bin/banner "$NUM"
          else
             echo $NUM
          fi
             NUM=$(($NUM-1))
             sleep 2
       done
    else
        echo "Error: number not specified."
        echo "Usage: $0 <number>"
        exit 1
    fi
    

NUM=${1:-0} significa:

% bl0ck_qu0te%

Fonte: link

No seu caso, isso significa que, se você passou um argumento para o script, NUM será igual a esse argumento, senão, NUM será igual a 0

    
por Helio 13.04.2015 / 18:05
2

A linha NUM=${1:-0} significa que a variável NUM está definida como $1 se um parâmetro for passado para o script e para 0 se nenhum parâmetro for passado. Isso explica por que você não tem saída alguma; o limite é sempre definido como 0 se o script for executado sem passar um parâmetro a ele, por exemplo:

bash <script_name>

* < script_name > = nome do seu script bash ;

ou:

./<script_name>

* < script_name > = nome do seu script bash ;

Então, o que você realmente precisa fazer é passar o número do limite para seu script após a execução, ou seja:

bash <script_name> <threshold_number>

* < script_name > = nome do seu script bash ; < número > = número de thresold

ou:

./<script_name> <threshold_number>

* < script_name > = nome do seu script bash ; < número > = número de thresold

    
por kos 13.04.2015 / 17:58

Tags