Pull to refresh

Взаимодействие bash-скриптов с пользователем

Reading time 4 min
Views 145K
Любой приказ, который может быть неправильно понят, понимается неправильно (Армейская аксиома)

Редкий скрипт лишен необходимости общения с пользователем. Мы ожидаем, что программа (утилита) будет выполнять то, что нам от нее хочется. Следовательно, нужны инструменты влияния на них, да и программа сама должна объяснить, как продвигается ее работа.
Данным топиком я хочу рассмотреть несколько способов взаимодействия bash-скриптов с пользователем. Статья рассчитана на новичков в скриптинге, но, надеюсь, люди опытные тоже найдут что-нибудь интересное для себя.

Топик так же снабжен примитивными примерами, не несущими смысловой нагрузки, но позволяющими посмотреть в работе некоторые интересные штуки.

Переменные


Самый распространенный способ хранения начальных данных — переменные. В самом начале программы объявляются несколько таких переменных, в которые пользователь записывает некоторые исходные данные.
#!/bin/bash

# Вписать сюда адрес электронной почты
EMAIL=example@gmail.com

echo "Адрес электронной почты: $EMAIL"

Такой способ хорош, если данных не много и скрипт рассчитан на автоматическое выполнение без участия пользователя. Необходимо ясно известить пользователя о том, что и где ему необходимо вписать. Желательно собрать все это в одном месте — файле конфигурации. Подключить его можно командой source. Например, если конфигурационный файл будет лежать в той же директории, что и скрипт, мы получим:
#!/bin/bash

source ./config.cfg

echo "Адрес электронной почты: $EMAIL"

В файл config.cfg не забудем поместить строчку EMAIL=example@gmail.com

Параметры командной строки


Еще один способ сообщить данные программе — указать при запуске в командной строке. Содержатся эти параметры в переменных с номерами. Например: $0 — имя скрипта, $1 — первый параметр, $2 — второй параметр и т. д. Также существуют две вспомогательные переменные: $# содержит количество переданных аргументов; $@ содержит все аргументы, переданные скрипту, разделенные пробелами.

#!/bin/bash

# Цикл выдаст все переданные аргументы
for n in $@
do
  echo "$n"
done



Вопросы и подтверждения



Думаю многим знаком вопрос со скриншота выше. Такой диалог можно использовать… ну вы и сами догадались, где его можно использовать.
#!/bin/bash

echo -n "Продолжить? (y/n) "

read item
case "$item" in
    y|Y) echo "Ввели «y», продолжаем..."
        ;;
    n|N) echo "Ввели «n», завершаем..."
        exit 0
        ;;
    *) echo "Ничего не ввели. Выполняем действие по умолчанию..."
        ;;
esac

Обратите внимание, что на скриншоте буква «Д» — большая. Это означает действие по умолчанию, то есть если пользователь ничего не введет, то это будет равнозначно вводу «Д».

OK / FAIL


Еще одним способом общения программы с пользователем являются статусы выполнения. Скорее всего они вам знакомы.

Реализация тоже довольно проста.
#!/bin/bash

SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_NORMAL="echo -en \\033[0;39m"

echo -e "Удаляется файл..."

# Команда, которую нужно отследить
rm test_file

if [ $? -eq 0 ]; then
    $SETCOLOR_SUCCESS
    echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]"
    $SETCOLOR_NORMAL
    echo
else
    $SETCOLOR_FAILURE
    echo -n "$(tput hpa $(tput cols))$(tput cub 6)[fail]"
    $SETCOLOR_NORMAL
    echo
fi

Вот так выглядит работа скрипта:

Хорошие люди написали расширенную версию скрипта с логированием и прогресом выполнения. С радостью поделюсь ссылкой.

Исходя из вышеприведенной ссылки код можно упростить.
#!/bin/bash

red=$(tput setf 4)
green=$(tput setf 2)
reset=$(tput sgr0)
toend=$(tput hpa $(tput cols))$(tput cub 6)

echo -e "Удаляется файл..."

# Команда, которую нужно отследить
rm test_file

if [ $? -eq 0 ]; then
    echo -n "${green}${toend}[OK]"
else
    echo -n "${red}${toend}[fail]"
fi
echo -n "${reset}"
echo


Псевдографика


Для любителей графического представления существуют удобный инструмент: dialog. По умолчанию его в системе нет, так что исправим положение.
sudo apt-get install dialog

Опробовать его можно простой командой:
dialog --title " Уведомление " --msgbox "\n Свершилось что-то страшное!" 6 50

Вот пример диалога прогресса:
#!/bin/sh

(
c=10
while [ $c -ne 110 ]
    do
        echo $c
        ((c+=10))
        sleep 1
done
) |
dialog --title " Тест диалога прогресса " --gauge "Please wait ...." 10 60 0

clear

Не забываем вставлять clear для очистки экрана, чтобы не оставлять синий фон. Эта утилита поддерживает еще очень много типов диалоговых окон. Главным недостатком является то, что по умолчанию ее нет в системе.

Альтернативой dialog может служить whiptail, который даже присутствует в некоторых системах по умолчанию.

Подробнее можно ознакомиться по ссылкам:
http://unstableme.blogspot.com/2009/12/linux-dialog-utility-short-tutorial.html
http://www.cc-c.de/german/linux/linux-dialog.php

GUI


Хоть есть ярые противники GUI, но он явно имеет право на существование. Такие диалоги можно получить с помощью команды kdialog (если графической оболочкой выступает KDE), либо gdialog и zenity (для Gnome).

Например, форма для ввода пароля:
kdialog --password "Пожалуйста, введите свой пароль:"

либо
gdialog --password "Пожалуйста, введите свой пароль:"

Еще пример один для KDE:
kdialog --question "Вы хотите продолжить?"
rc=$?
if [ "${rc}" == "0" ]; then
    echo "Нажали yes"
else
    echo "Нажали no"
fi

И для Gnome:
#!/bin/bash

name=$(gdialog --title "Ввод данных" --inputbox "Введите ваше имя:" 50 60 2>&1)
echo "Ваше имя: $name"

Как видите, явным недостатком этого метода является привязанность к конкретной среде рабочего стола. Да и вообще к графической среде, которая может и отсутствовать. Но, тем не менее, может и пригодиться когда-нибудь.

Подробнее по ссылкам:
http://pwet.fr/man/linux/commandes/kdialog
http://linux.about.com/library/cmd/blcmdl1_gdialog.htm
http://www.techrepublic.com/blog/opensource/gui-scripting-in-bash/1667

P.S. Продолжение следует…

UPD: Добавил упрощенный код в раздел «OK / FAIL».
UPD2: Добавил пример подключения конфигурационного файла в раздел «Переменные».

Опубликована вторая часть.
Tags:
Hubs:
+85
Comments 48
Comments Comments 48

Articles