Любой приказ, который может быть неправильно понят, понимается неправильно (Армейская аксиома)
Редкий скрипт лишен необходимости общения с пользователем. Мы ожидаем, что программа (утилита) будет выполнять то, что нам от нее хочется. Следовательно, нужны инструменты влияния на них, да и программа сама должна объяснить, как продвигается ее работа.
Данным топиком я хочу рассмотреть несколько способов взаимодействия 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
Обратите внимание, что на скриншоте буква «Д» — большая. Это означает действие по умолчанию, то есть если пользователь ничего не введет, то это будет равнозначно вводу «Д».
Еще одним способом общения программы с пользователем являются статусы выполнения. Скорее всего они вам знакомы.
Реализация тоже довольно проста.
#!/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
tput hpa N — сдвиг курсора на N позиций
tput cols получает ширину окна терминала
tput cub 6 — сдвигает курсор на 6 позиций влево
tput setaf 0..7 — цвет текста
tput setab 0..7 — цвет фона
tput srg0 — сброс на дефолтный
Для любителей графического представления существуют удобный инструмент: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, но он явно имеет право на существование. Такие диалоги можно получить с помощью команды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