Скрипт обратного отсчета не работает

Я пытаюсь создать скрипт, который будет отсчитывать до 0 от любого числа, которое я ему даю. Ниже приведен мой сценарий, и в основном ничего не происходит, никаких сообщений об ошибках, я просто получаю стандартную подсказку командной строки.

#!/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
5
задан 13 April 2015 в 18:47

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

вывод:

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

объяснение:
в Ђ1. строка 3 подсказки пользователь для ввода целого числа и чтений это в переменную ЦИФРУ.
в Ђ2. Измененный -gt в строке 6 к -ge так, чтобы это считало в обратном порядке для обнуления.
в Ђ3. Вывод отображен в формате баннера, если sysvbanner установлен или иначе как текст, если это не.

3
ответ дан 13 April 2015 в 18:47

NUM=${1:-0} строка означает, что переменная NUM установлена на $1, если параметр передается сценарию, и 0, если никакой параметр не передается вообще. Это объясняет, почему у Вас нет вывода вообще; порог всегда устанавливается к 0, если сценарий выполняется, не передавая параметр ему, например:

bash <script_name>

*< script_name> = название Вашего bash сценарий;

или:

./<script_name>

*< script_name> = название Вашего bash сценарий;

, Таким образом, что действительно необходимо сделать, необходимо просто передать пороговое число сценарию после выполнения, т.е.:

bash <script_name> <threshold_number>

*< script_name> = название Вашего bash сценарий; < number> = thresold номер

или:

./<script_name> <threshold_number>

*< script_name> = название Вашего bash сценарий; < number> = thresold номер

2
ответ дан 13 April 2015 в 18:47

Улучшенный и прокомментировал код:

#!/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.

Вышеупомянутый код будет включать нуль в обратный отсчет, если сделают Вы хотите остановиться, когда обратный отсчет достигает 1, затем только необходимо внести несколько изменений:

  1. В 6-й строке, изменении ^[0-9]+$ ^[1-9]+[0-9]*$ таким образом, это похоже на это:

    until [[ "$num" =~ ^[1-9]+[0-9]*$ ]]; do              # Until $num become a valid number (loop will not be executed if $1 is set):
    
  2. В 10-й строке удалите = подпишитесь, таким образом, это похоже на это (я обновил также комментарий):

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

Ваша исходная программа не работает потому что:

  • Вы не переданный число как аргумент программе.
  • Вызов в качестве примера этой команды ./countdown 5 где 5 число.
  • Если делают Вы хотите обработать это, можно добавить a else к Вашему коду (смотрят пять последних строк):

    #!/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} средства:

${PARAMETER:-WORD}

Если параметр PARAMETER сброшен (никогда не определялся), или (пустой) пустой указатель, этот расширяется до WORD, иначе это расширяется до значения PARAMETER, как будто это просто было ${PARAMETER}.

echo "Your home directory is: ${HOME:-/home/$USER}."
echo "${HOME:-/home/$USER} will be used to store your personal data."

Если HOME сброшен или пуст, каждый раз Вы хотите распечатать что-то полезное, необходимо вставить тот синтаксис параметра.

Источник: http://wiki.bash-hackers.org/syntax/pe#use_a_default_value

В Вашем случае это означает это при передаче аргумента сценарию, NUM будет равно тому аргументу, еще, NUM будет равно 0

3
ответ дан 13 April 2015 в 18:47

Другие вопросы по тегам:

Похожие вопросы: