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

Я пытаюсь создать скрипт, который будет отсчитывать до 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
1
задан 13 April 2015 в 18:47

2 ответа

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

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

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

В 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):
В 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 - это число. Если вы хотите справиться с этим, вы можете добавить 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 не задан (никогда не был определен) или null (пустой), он расширяется до 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
ответ дан 23 May 2018 в 21:26
  • 1
    @Arronical: Исправлено! Благодаря! – Helio 14 April 2015 в 14:12
  • 2
    Почему числовое регулярное выражение допускает отрицательные числа? Тем не менее, мне все равно нравится ваш улучшенный код. – Oli♦ 14 April 2015 в 14:19
  • 3
    @Oli: Извините, была ошибка, исправлена! – Helio 14 April 2015 в 14:30
  • 4
    @Oli: Вы можете исправить мой ответ? Английский не мой родной язык. – Helio 14 April 2015 в 15:33
  • 5
    COMMAND=$(which banner || which echo) возвращается к исполняемому файлу echo, а не к встроенной оболочке. В bash (этот скрипт уже использует специфичные для bash функции) у вас есть встроенное эхо и может также использовать его. Кроме того, если здесь используется командная подстановка, то в нечетном случае пробелов в полном пути баннера ($PATH записи могут содержать пробельные символы, хотя лучше их избегать), вероятно, это должно использоваться как "$COMMAND" $NUM позже в скрипте. Вместо этого я предлагаю использовать which banner && COMMAND=banner || COMMAND=echo или аналогичный . – Eliah Kagan 15 April 2015 в 15:07

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

bash <script_name>

* & lt; имя_страницы & gt; = имя вашего скрипта bash;

или:

./<script_name>

* & lt; script_name & gt; = имя вашего скрипта bash;

Итак, вам действительно нужно просто передать пороговое число вашему сценарию после выполнения, т. е.

bash <script_name> <threshold_number>
* & л; имя_скрипта & GT; = имя вашего скрипта bash; & Lt; & номер GT; = thresold number

или:

./<script_name> <threshold_number>

* & lt; script_name & gt; = имя вашего скрипта bash; & Lt; & номер GT; = thresold number

2
ответ дан 23 May 2018 в 21:26
  • 1
    Кто бы ни отклонил этот пост, должен знать, что он / она будет очень приветствовать, чтобы объяснить, что с ним не так – kos 13 April 2015 в 19:17

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

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