Любой приказ, который может быть неправильно понят, понимается неправильно (Армейская аксиома)
Редкий скрипт лишен необходимости общения с пользователем. Мы ожидаем, что программа (утилита) будет выполнять то, что нам от нее хочется. Следовательно, нужны инструменты влияния на них, да и программа сама должна объяснить, как продвигается ее работа.
Данным топиком я хочу рассмотреть несколько способов взаимодействия 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: Добавил пример подключения конфигурационного файла в раздел «Переменные».
Опубликована вторая часть.