
- •Содержание
- •Часть 1. Введение
- •Глава 1. Зачем необходимо знание языка Shell?
- •Глава 2. Для начала о Sha-Bang
- •Часть 2. Основы
- •Глава 3. Служебные символы
- •Глава 4. Переменные и параметры. Введение.
- •Глава 5. Кавычки
- •Глава 6. Завершение и код завершения
- •Глава 7. Проверка условий
- •Глава 8. Операции и смежные темы
- •Часть 3. Углубленный материал
- •Глава 9. К вопросу о переменных
- •Глава 10. Циклы и ветвления
- •Глава 11. Внутренние команды
- •Глава 12. Внешние команды, программы и утилиты
- •Глава 13. Команды системного администрирования
- •Глава 14. Подстановка команд
- •Глава 15. Арифметические подстановки
- •Глава 16. Перенаправление ввода/вывода
- •Глава 17. Встроенные документы
- •Часть 4. Материал повышенной сложности
- •Глава 18. Регулярные выражения
- •Глава 19. Подоболочки, или Subshells
- •Глава 20. Ограниченный режим командной оболочки
- •Глава 21. Подстановка процессов
- •Глава 22. Функции
- •Глава 23. Псевдонимы
- •Глава 24. Списки команд
- •Глава 25. Массивы
- •Глава 26. Файлы
- •Глава 27. /dev и /proc
- •Глава 28. /dev/zero и /dev/null
- •Глава 29. Отладка сценариев
- •Глава 30. Необязательные параметры (ключи)
- •Глава 31. Широко распространенные ошибки
- •Глава 32. Стиль программирования
- •Глава 33. Разное
- •Глава 34. Bash, версия 2
- •Глава 35. Замечания и дополнения
- •Библиография
- •Приложение B. Справочная информация
- •Приложение D. Коды завершения, имеющие предопределенный смысл
- •Приложение F. Системные каталоги
- •Приложение G. Локализация
- •Приложение H. История команд
- •Приложение I. Пример файла .bashrc
- •Приложение J. Преобразование пакетных (*.bat) файлов DOS в сценарии командной оболочки
- •Приложение K. Упражнения
- •Приложение L. Хронология
- •Приложение M. Авторские права

Приложение G. Локализация
Возможность локализации сценариев Bash нигде в документации не описана.
Локализованные сценарии выводят текст на том языке, который используется системой, в соответствии с настройками. Пользователь Linux, живущий в Берлине (Германия), будет видеть сообщения на немецком языке, в то время как другой пользователь, проживающий в Берлине штата Мэриленд (США) -- на английском.
Для создания локализованых сценариев можно использовать следующий шаблон, предусматривающий вывод всех сообщений на языке пользователя (сообщения об ошибках, приглашения к вводу и т.п.).
#!/bin/bash
# localized.sh
# Автор Stephane Chazelas, дополнил Bruno Haible
. gettext.sh E_CDERROR=65 error()
{ printf "$@" >&2 } exit $E_CDERROR
cd $var || error "`eval_gettext \"Can't cd to \$var.\"`" read -p "`gettext \"Enter the value: \"`" var
# ...
bash$ bash -D localized.sh
"Can't cd to %s." "Enter the value: "
Это список всех текстовых сообщений, которые подлежат локализации. (Ключ -D выводит список строк в двойных кавычках, которым предшествует символ $, без запуска сценария на исполнение.)
bash$ bash --dump-po-strings localized.sh
#: a:6
msgid "Can't cd to %s." msgstr ""
#: a:7
msgid "Enter the value: " msgstr ""
Ключ --dump-po-strings в Bash напоминает ключ -D, но выводит строки в формате "po", с помощью утилиты gettext.
Bruno Haible отмечает, что:
Начиная с версии gettext-0.12.2, вместо bash --dump-po-strings localized.sh, рекомендуется использовать xgettext -o - localized.sh, потому что xgettext . . .
1.понимает команды gettext и eval_gettext (тогда как bash --dump-po-strings только свой синтаксис в виде $"..." )
2.может извлекать комментарии программиста, предназначенные для переводчика.
427

Такой код не привязан к определенной версии Bash и может быть исполнен в Bash 1.x или
других реализациях /bin/sh.
Теперь построим файл language.po, для каждого языка, на которые предполагается перевести сообщения сценария. Например:
Файл ru.po сделан переводчиком, в оригинальном документе локализация выполнена на примере французского языка
ru.po:
#: a:6
msgid "Can't cd to %s."
msgstr "Невозможно перейти в каталог %s." #: a:7
msgid "Enter the value: " msgstr "Введите число: "
Затем запустите msgfmt.
msgfmt -o localized.sh.mo ru.po
Перепишите получившийся файл localized.sh.mo в каталог /usr/share/locale/ru/LC_MESSAGES и
добавьте в начало сценария строки:
TEXTDOMAINDIR=/usr/share/locale
TEXTDOMAIN=localized.sh
Если система корректно настроена на русскую локаль, то пользователь, запустивший сценарий, будет видеть сообщения на русском языке.
В старых версиях Bash или в других командных оболочках, потребуется воспользоваться услугами утилиты gettext, с ключом -s. В этом случае наш сценарий будет выглядеть так:
#!/bin/bash
# localized.sh E_CDERROR=65
error() {
local format=$1 shift
printf "$(gettext -s "$format")" "$@" >&2 } exit $E_CDERROR
cd $var || error "Can't cd to %s." "$var"
read -p "$(gettext -s "Enter the value: ")" var
# ...
А переменные TEXTDOMAIN и TEXTDOMAINDIR, необходимо будет экспортировать в окружение.
---
Это приложение написано Stephane Chazelas, и дополнено Bruno Haible, ведущим разработчиком GNU
428

gettext.
Приложение H. История команд
Командная оболочка Bash предоставляет в распоряжение пользователя инструментарий командной строки, позволяющий управлять историей команд. История команд -- это, прежде всего, очень удобный инструмент, сокращающий ручной ввод.
История команд Bash:
1.history
2.fc
bash$ history |
|
1 |
mount /mnt/cdrom |
2 |
cd /mnt/cdrom |
3 |
ls... |
Внутренние переменные Bash, связанные с историей команд:
1.$HISTCMD
2.$HISTCONTROL
3.$HISTIGNORE
4.$HISTFILE
5.$HISTFILESIZE
6.$HISTSIZE
7.!!
8.!$
9.!#
10.!N
11.!-N
12.!STRING
13.!?STRING?
14.^STRING^string^
429

К сожалению, инструменты истории команд, в Bash, совершенно бесполезны в сценариях.
#!/bin/bash
# history.sh
# Попытка воспользоваться 'историей' команд в сценарии. history
# На экран ничего не выводится.
# История команд не работает в сценариях.
bash$ ./history.sh
(ничего не выводится)
Приложение I. Пример файла .bashrc
Файл ~/.bashrc определяет поведение командной оболочки. Внимательное изучение этого примера поможет вам значительно продвинуться в понимании Bash.
Emmanuel Rouat представил следующий, очень сложный, файл .bashrc, написанный для операционной системы Linux. Предложения и замечания приветствуются.
Внимательно изучите этот файл. Отдельные участки этого файла вы свободно можете использовать в своем собственном .bashrc или, даже в своих сценариях!
Пример I-1. Пример файла .bashrc
#===============================================================
#
# ЛИЧНЫЙ ФАЙЛ $HOME/.bashrc для bash-2.05a (или выше)
#
# Время последней модификации: Втр Апр 15 20:32:34 CEST 2003
#
# Этот файл содержит настройки интерактивной командной оболочки.
# Здесь размещены определения псевдонимов, функций
# и других элементов Bash, таких как prompt (приглашение к вводу).
#
# Изначально, этот файл был создан в операционной системе Solaris,
# но позднее был переделан под Redhat
# --> Модифицирован под Linux.
# Большая часть кода, который находится здесь, была взята из
# Usenet (или Интернет).
# Этот файл содержит слишком много определений -- помните, это всего лишь пример.
#
#
#===============================================================
#--> Комментарии, добавленные автором HOWTO.
#--> И дополнены автором сценария Emmanuel Rouat :-)
#----------------------------------- |
|
# Глобальные определения |
|
#----------------------------------- |
|
if [ -f /etc/bashrc ]; then |
|
. /etc/bashrc |
# --> Прочитать настройки из /etc/bashrc, если таковой имеется. |
fi |
|
430
#------------------------------------------------------------- |
|
|
|
|
|
|
|
# Настройка переменной $DISPLAY (если еще не установлена) |
|||||||
# Это |
срабатывает под linux - в вашем |
случае все может быть по другому.... |
|||||
# Проблема в том, что различные типы терминалов |
|
||||||
# дают разные ответы на запрос 'who am i'...... |
|
||||||
# я не нашел 'универсального' метода |
|
|
|||||
#------------------------------------------------------------- |
|
|
|
|
|
|
|
function get_xserver () |
|
|
|
|
|||
{ |
case $TERM |
in |
|
|
|
|
|
|
|
xterm |
) |
|
|
|
|
|
|
XSERVER=$(who am i | awk '{print $NF}' | tr -d ')''(' ) |
|||||
|
|
XSERVER=${XSERVER%%:*} |
|
|
|||
|
|
;; |
| rxvt) |
|
|
|
|
|
|
aterm |
|
|
|
|
|
|
|
# добавьте здесь свой код..... |
|
|
|||
|
|
;; |
|
|
|
|
|
} |
esac |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if [ -z ${DISPLAY:=""} ]; then |
|
|
|
||||
|
get_xserver |
|| ${XSERVER} == $(hostname) || ${XSERVER} == "unix" ]]; then |
|||||
|
if [[ -z ${XSERVER} |
||||||
|
|
DISPLAY=":0.0" |
|
# для |
локального |
хоста |
|
|
elseDISPLAY=${XSERVER}:0.0 |
# для |
удаленного |
хоста |
|||
fi |
fi |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export DISPLAY |
|
|
|
|
|
||
#--------------- |
|
|
|
|
|
|
|
# Некоторые настройки |
|
|
|
|
|||
#--------------- |
|
|
|
|
|
|
|
ulimit -S -c 0 |
|
# Запрет на создание файлов coredump |
|||||
set |
-o notify |
|
|
|
|
|
|
set |
-o noclobber |
|
|
|
|
||
set |
-o ignoreeof |
|
|
|
|
||
set |
-o nounset |
|
# полезно для |
отладки |
|
||
#set |
|
-o xtrace |
|
|
|||
# Разрешающие настройки: |
|
|
|
|
|||
shopt |
-s cdspell |
|
|
|
|
||
shopt -s cdable_vars |
|
|
|
|
|||
shopt |
-s checkhash |
|
|
|
|
||
shopt |
-s checkwinsize |
|
|
|
|
||
shopt |
-s mailwarn |
|
|
|
|
||
shopt |
-s sourcepath |
|
|
|
|
||
shopt |
-s no_empty_cmd_completion # только для bash>=2.04 |
||||||
shopt |
-s cmdhist |
|
|
|
|
||
shopt -s histappend histreedit histverify |
|
||||||
shopt |
-s extglob |
|
|
|
|
||
# Запрещающие настройки: |
|
|
|
|
|||
shopt |
-u mailwarn |
# Я не желаю, чтобы командная оболочка сообщала мне о прибытии почты |
|||||
unset |
MAILCHECK |
||||||
export TIMEFORMAT=$'\nreal %3R\tuser %3U\tsys %3S\tpcpu %P\n' |
|||||||
export HISTIGNORE="&:bg:fg:ll:h" |
# Поместить список удаленных хостов в файл ~/.hosts |
||||||
export HOSTFILE=$HOME/.hosts |
|||||||
#----------------------- |
|
|
|
|
|
|
|
# Greeting, motd etc... |
|
|
|
|
|||
#----------------------- |
|
|
|
|
|
|
|
# Для начала определить некоторые цвета: |
|
||||||
red='\e[0;31m' |
|
|
|
|
|
||
RED='\e[1;31m' |
|
|
|
|
|
||
blue='\e[0;34m' |
|
|
|
|
|||
BLUE='\e[1;34m' |
|
|
|
|
|||
cyan='\e[0;36m' |
|
|
|
|
|||
CYAN='\e[1;36m' |
# No Color (нет цвета) |
|
|||||
NC='\e[0m' |
|
|
# --> Прекрасно. Имеет тот же эффект, что и "ansi.sys" в DOS.
# Лучше выглядит на черном фоне.....
431
echo -e "${CYAN}This is BASH ${RED}${BASH_VERSION%.*}${CYAN} - DISPLAY on ${RED}$DISPLAY${NC}\n" |
||||||||
date |
|
|
|
|
|
|
|
|
if [ -x /usr/games/fortune ]; then |
|
|
|
|||||
/usr/games/fortune -s |
# сделает наш день более интересным.... :-) |
|||||||
fi |
|
|
|
|
|
|
|
|
function |
_exit() |
|
# функция, запускающаяся при выходе из оболочки |
|||||
{ |
|
|
|
|
|
|
|
|
echo -e "${RED}Аста ла виста, бэби ${NC}" |
|
|
||||||
} |
|
|
|
|
|
|
|
|
trap _exit EXIT |
|
|
|
|
|
|
||
#--------------- |
|
|
|
|
|
|
||
# Prompt |
|
|
|
|
|
|
|
|
#--------------- |
|
|
|
|
|
|
||
if [[ "${DISPLAY#$HOST}" != ":0.0" && "${DISPLAY}" != ":0" ]]; |
then |
|||||||
HILIT=${red} |
# на удаленной |
системе: prompt будет |
частично |
красным |
||||
elseHILIT=${cyan} |
# на локальной |
системе: prompt будет |
частично |
циановым |
||||
fi |
|
|
|
|
|
|
|
|
# --> Замените \W на \w в функциях ниже |
|
|
||||||
#+ --> чтобы видеть в оболочке полный путь к текущему каталогу. |
|
|||||||
function |
fastprompt() |
|
|
|
|
|
||
{ |
PROMPT_COMMAND |
|
|
|
|
|||
unset |
|
|
|
|
||||
case |
$TERM |
in |
|
|
|
|
|
|
*term |
| rxvt ) |
|
|
|
|
|
||
|
PS1="${HILIT}[\h]$NC \W > \[\033]0;\${TERM} [\u@\h] \w\007\]" ;; |
|||||||
linux |
) |
|
|
|
|
|
|
|
|
PS1="${HILIT}[\h]$NC \W > " ;; |
|
|
|||||
*) |
|
|
|
|
|
|
|
|
esac |
PS1="[\h] \W > " ;; |
|
|
|
||||
} |
|
|
|
|
|
|
|
|
function |
powerprompt() |
|
|
|
|
|
||
{ |
|
|
|
|
|
|
|
|
_powerprompt() |
|
|
|
|
|
|
||
{ |
|
|
|
|
|
|
|
|
LOAD=$(uptime|sed -e "s/.*: \([^,]*\).*/\1/" -e "s/ //g") |
||||||||
} |
|
|
|
|
|
|
|
|
PROMPT_COMMAND=_powerprompt |
|
|
|
|||||
case |
$TERM |
in |
|
) |
|
|
|
|
*term |
| rxvt |
|
|
|
|
|||
|
PS1="${HILIT}[\A \$LOAD]$NC\n[\h \#] \W > \[\033]0;\${TERM} [\u@\h] \w\007\]" ;; |
|||||||
linux |
) |
|
|
|
|
|
|
|
|
PS1="${HILIT}[\A - \$LOAD]$NC\n[\h \#] \w > " ;; |
|
||||||
* ) PS1="[\A - \$LOAD]\n[\h \#] \w > " ;; |
|
|
||||||
esac |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
powerprompt |
# это prompt по-умолчанию - может работать довольно медленно |
|||||||
|
|
# Если |
это |
так, то используйте fastprompt.... |
|
#===============================================================
#
# ПСЕВДОНИМЫ И ФУНКЦИИ
#
# Возможно некоторые из функций, приведенных здесь, окажутся для вас слишком большими,
# но на моей рабочей станции установлено 512Mb ОЗУ, так что.....
# Если пожелаете уменьшить размер этого файла, то можете оформить эти функции
# в виде отдельных сценариев.
#
# Большинство функций были взяты, почти без переделки, из примеров
# к bash-2.04.
#
#===============================================================
#-------------------
# Псевдонимы
#-------------------
alias rm='rm -i' alias cp='cp -i' alias mv='mv -i'
# -> Предотвращает случайное удаление файлов.
432
alias |
mkdir='mkdir -p' |
|
|
|
||
alias |
h='history' |
|
|
|
||
alias |
j='jobs -l' |
|
|
|
||
alias |
r='rlogin' |
|
|
|
||
alias |
which='type -all' |
|
|
|
||
alias ..='cd ..' |
|
|
|
|||
alias path='echo -e ${PATH//:/\\n}' |
|
# Предполагается, что LPDEST определен |
||||
alias |
print='/usr/bin/lp -o nobanner -d $LPDEST' |
|||||
alias |
pjet='enscript -h -G -fCourier9 -d $LPDEST' |
# Печать через enscript |
||||
alias |
background='xv -root -quit |
-max -rmode |
5' |
# Положить картинку в качестве фона |
||
alias |
du='du -kh' |
|
|
|
||
alias |
df='df -kTh' |
|
|
|
||
# Различные варианты 'ls' (предполагается, что установлена GNU-версия ls) |
||||||
alias |
la='ls -Al' |
# показать скрытые файлы |
||||
alias |
ls='ls -hF --color' |
# выделить различные типы файлов цветом |
||||
alias |
lx='ls -lXB' |
# сортировка |
по расширению |
|||
alias |
lk='ls -lSr' |
# сортировка |
по размеру |
|||
alias |
lc='ls -lcr' |
# сортировка по времени изменения |
||||
alias |
lu='ls -lur' |
# сортировка по времени последнего обращения |
||||
alias |
lr='ls -lR' |
# рекурсивный обход подкаталогов |
||||
alias |
lt='ls -ltr' |
# сортировка |
по дате |
|||
alias |
lm='ls -al |more' |
# вывод через |
'more' |
|||
alias |
tree='tree -Csu' |
# альтернатива 'ls' |
||||
# подготовка |
'less' |
|
|
|
||
alias |
more='less' |
|
|
|
||
export PAGER=less |
|
|
|
|||
export LESSCHARSET='latin1' |
|
|
|
|||
export LESSOPEN='|/usr/bin/lesspipe.sh %s 2>&-' # если существует lesspipe.sh |
||||||
export LESS='-i -N -w -z-4 -g -e -M -X -F -R -P%t?f%f \ |
||||||
:stdin .?pb%pb\%:?lbLine %lb:?bbByte %bb:-...' |
|
|||||
# проверка правописания - настоятельно рекомендую :-) |
||||||
alias |
xs='cd' |
|
|
|
|
|
alias |
vf='cd' |
|
|
|
|
|
alias |
moer='more' |
|
|
|
||
alias |
moew='more' |
|
|
|
||
alias |
kk='ll' |
|
|
|
|
|
#---------------- |
|
|
|
|||
# добавим немножко "приятностей" |
|
|
|
|||
#---------------- |
|
|
|
|||
function |
xtitle () |
|
|
|
||
{ |
|
"$TERM" in |
|
|
|
|
case |
|
|
|
|||
|
|
*term |
| rxvt) |
|
|
|
|
|
echo -n -e "\033]0;$*\007" ;; |
|
|
||
|
|
*) |
|
|
|
|
esac |
;; |
|
|
|
||
} |
|
|
|
|
|
|
# псевдонимы... |
|
|
|
|||
alias top='xtitle Processes on $HOST && top' |
|
|
||||
alias make='xtitle Making $(basename $PWD) ; make' |
|
|||||
alias ncftp="xtitle ncFTP ; ncftp" |
|
|
||||
# .. и функции |
|
|
|
|||
function |
man |
() |
|
|
|
|
{ |
|
i ; do |
|
|
|
|
for |
|
|
|
|||
|
|
xtitle The $(basename $1|tr -d .[:digit:]) manual |
||||
donecommand man -F -a "$i" |
|
|
|
|||
} |
|
|
|
|
|
|
function ll(){ ls -l "$@"| egrep "^d" ; ls -lXB "$@" 2>&-| egrep -v "^d|total "; } |
||||||
function |
te() |
# "обертка" вокруг xemacs/gnuserv |
|
|||
{ |
|
|
|
|
|
|
if [ "$(gnuclient -batch -eval t 2>&-)" == "t" ]; then |
||||||
elsegnuclient -q "$@"; |
|
|
|
|||
fi |
|
( xemacs "$@" &); |
|
|
|
|
} |
|
|
|
|
|
|
#----------------------------------- |
|
|
||||
# Функции для |
работы с файлами и строками: |
|
|
433
#-----------------------------------
# Поиск файла по шаблону:
function ff() { find . -type f -iname '*'$*'*' -ls ; }
# Поиск файла по шаблону в $1 и запуск команды в $2 с ним:
function fe() { find . -type f -iname '*'$1'*' -exec "${2:-file}" {} \; ; }
# поиск строки по файлам: function fstr()
{
OPTIND=1 local case=""
local usage="fstr: поиск строки в файлах.
Порядок использования: fstr [-i] \"шаблон\" [\"шаблон_имени_файла\"] " while getopts :it opt
do
case "$opt" in i) case="-i " ;;
*) echo "$usage"; return;; doneesac
shift $(( $OPTIND - 1 )) if [ "$#" -lt 1 ]; then
fi
echo "$usage" return;
local SMSO=$(tput smso) local RMSO=$(tput rmso)
find . -type f -name "${2:-*}" -print0 | xargs -0 grep -sn ${case} "$1" 2>&- | \ sed "s/$1/${SMSO}\0${RMSO}/gI" | more
}
function cuttail() # удалить последние n строк в файле, по-умолчанию 10 |
||
{ |
|
|
nlines=${2:-10} |
|
|
sed -n -e :a -e "1,${nlines}!{P;N;D;};N;ba" $1 |
||
} |
|
|
function |
lowercase() |
# перевести имя файла в нижний регистр |
{ |
file ; do |
|
for |
|
|
|
filename=${file##*/} |
|
|
case "$filename" in |
|
|
*/*) dirname==${file%/*} ;; |
|
|
*) dirname=.;; |
|
|
esac |
|
|
nf=$(echo $filename | tr A-Z a-z) |
|
|
newname="${dirname}/${nf}" |
|
|
if [ "$nf" != "$filename" ]; then |
|
|
mv "$file" "$newname" |
|
|
elseecho "lowercase: $file --> $newname" |
|
|
echo "lowercase: имя файла $file не было изменено." |
|
donefi |
|
|
} |
|
|
function |
swap() |
# меняет 2 файла местами |
{ |
|
|
local TMPFILE=tmp.$$ |
||
mv "$1" $TMPFILE |
|
|
mv "$2" "$1" |
|
|
mv $TMPFILE "$2" |
|
|
} |
|
|
# Эта функция является грубым аналогом 'killall' в linux |
|||
# но не эквивалентна (насколько я знаю) 'killall' в Solaris |
|||
function |
killps() |
# "Прибить" процесс по его имени |
|
{ |
pid pname |
sig="-TERM" |
# сигнал, рассылаемый поумолчанию |
local |
|||
#----------------------------------- |
|
|
|
# Функции для работы с процессами/системой: |
|||
#----------------------------------- |
|
|
|
function my_ps() { ps $@ -u $USER -o pid,%cpu,%mem,bsdtime,command ; } function pp() { my_ps f | awk '!/awk/ && $0~var' var=${1:-".*"} ; }
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
echo "Порядок использования: killps [-SIGNAL] шаблон_имени_процесса" return;
fi
434
}
function my_ip() # IP адрес |
|
|
|||
{ |
|
|
|
|
|
MY_IP=$(/sbin/ifconfig ppp0 | awk '/inet/ { print $2 } ' | sed -e s/addr://) |
|||||
MY_ISP=$(/sbin/ifconfig ppp0 |
| awk '/P-t-P/ { print $3 } ' | sed -e s/P-t-P://) |
||||
} |
|
|
|
|
|
function |
ii() |
# Дополнительные |
сведения о системе |
||
{ |
|
|
|
|
|
echo -e "\nВы находитесь на ${RED}$HOST" |
|||||
echo -e "\nДополнительная информация:$NC " ; uname -a |
|||||
echo -e "\n${RED}В системе работают пользователи:$NC " ; w -h |
|||||
echo -e "\n${RED}Дата:$NC " ; date |
|||||
echo -e "\n${RED}Время, прошедшее с момента последней перезагрузки :$NC " ; uptime |
|||||
echo -e "\n${RED}Память :$NC " ; free |
|||||
my_ip 2>&- ; |
|
|
|
||
echo -e "\n${RED}IP адрес:$NC" ; echo ${MY_IP:-"Соединение не установлено"} |
|||||
echo -e "\n${RED}Адрес провайдера (ISP):$NC" ; echo ${MY_ISP:-"Соединение не установлено"} |
|||||
echo |
|
|
|
|
|
} |
|
|
|
|
|
# Разные утилиты: |
|
|
|
||
function |
repeat() |
# повторить |
команду n раз |
||
{ |
i max |
|
|
|
|
local |
|
|
|
|
|
max=$1; shift; |
|
|
# --> C-подобный синтаксис |
||
for ((i=1; i <= max ; i++)); do |
|||||
doneeval "$@"; |
|
|
|
||
} |
|
|
|
|
|
function |
ask() |
|
|
|
|
{
echo -n "$@" '[y/n] ' ; read ans case "$ans" in
}
y*|Y*) return 0 ;; esac*) return 1 ;;
#=========================================================================
#
# ПРОГРАММНЫЕ ДОПОЛНЕНИЯ - ТОЛЬКО НАЧИНАЯ С ВЕРСИИ BASH-2.04
# Большая часть дополнений взята из докуентации к bash 2.05 и из
# пакета 'Bash completion' (http://www.caliban.org/bash/index.shtml#completion)
# автор -- Ian McDonalds
# Фактически, у вас должен стоять bash-2.05a
#
#=========================================================================
if [ "${BASH_VERSION%.*}" \< "2.05" ]; then |
||
echo "Вам необходимо обновиться до версии 2.05" |
||
return |
|
|
fi |
|
|
shopt -s extglob |
# необходимо |
|
set +o nounset |
# иначе некоторые дополнения не будут работать |
|
complete |
-A hostname |
rsh rcp telnet rlogin r ftp ping disk |
complete |
-A export |
printenv |
complete |
-A variable |
export local readonly unset |
complete |
-A enabled |
builtin |
complete |
-A alias |
alias unalias |
complete |
-A function |
function |
complete |
-A user |
su mail finger |
complete |
-A helptopic |
help |
complete |
-A shopt |
shopt |
complete -A stopped -P '%' bg |
||
complete -A job -P '%' |
fg jobs disown |
|
complete |
-A directory |
mkdir rmdir |
|
|
435 |
complete -A directory |
-o default cd |
|
# Архивация |
|
zip |
complete -f -o default -X '*.+(zip|ZIP)' |
||
complete -f -o default -X '!*.+(zip|ZIP)' |
unzip |
|
complete -f -o default -X '*.+(z|Z)' |
compress |
|
complete -f -o default -X '!*.+(z|Z)' |
uncompress |
|
complete -f -o default -X '*.+(gz|GZ)' |
gzip |
|
complete -f -o default -X '!*.+(gz|GZ)' |
gunzip |
|
complete -f -o default -X '*.+(bz2|BZ2)' |
bzip2 |
|
complete -f -o default -X '!*.+(bz2|BZ2)' |
bunzip2 |
|
# Postscript,pdf,dvi..... |
|
|
complete -f -o default -X '!*.ps' gs ghostview ps2pdf ps2ascii |
||
complete -f -o default -X '!*.dvi' dvips dvipdf xdvi dviselect dvitype |
||
complete -f -o default -X '!*.pdf' acroread pdf2ps |
||
complete -f -o default -X '!*.+(pdf|ps)' gv |
||
complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf |
||
complete -f -o default -X '!*.tex' tex latex slitex |
||
complete -f -o default -X '!*.lyx' lyx |
|
|
complete -f -o default -X '!*.+(htm*|HTM*)' lynx html2ps |
||
# Multimedia |
|
|
complete -f -o default -X '!*.+(jp*g|gif|xpm|png|bmp)' xv gimp |
||
complete -f -o default -X '!*.+(mp3|MP3)' |
mpg123 mpg321 |
|
complete -f -o default -X '!*.+(ogg|OGG)' |
ogg123 |
complete -f -o default -X '!*.pl' perl perl5
#Эти 'универсальные' дополнения работают тогда, когда команды вызываются
#с, так называемыми, 'длинными ключами', например: 'ls --all' вместо 'ls -a'
_get_longopts ()
{
$1 --help | sed -e '/--/!d' -e 's/.*--\([^[:space:].,]*\).*/--\1/'| \ grep ^"$2" |sort -u ;
}
_longopts_func () |
|
||
{ |
|
|
|
case "${2:-*}" in |
|
||
-*) |
;; |
|
|
esac*) |
return ;; |
|
|
case "$1" in |
eval cmd="$1" ;; |
|
|
\~*) |
|
||
esac*) |
cmd="$1" ;; |
|
|
COMPREPLY=( $(_get_longopts ${1} ${2} ) ) |
|||
} |
-o default -F _longopts_func |
configure bash |
|
complete |
|||
complete |
-o default -F _longopts_func |
wget id info a2ps ls recode |
|
_make_targets () |
|
|
|
{ |
|
|
|
local mdef makef gcmd cur prev i |
|
||
COMPREPLY=() |
|
|
|
cur=${COMP_WORDS[COMP_CWORD]} |
|
||
prev=${COMP_WORDS[COMP_CWORD-1]} |
|
||
# Если |
аргумент prev это -f, то вернуть возможные варианты имен файлов. |
||
# будем великодушны и вернем несколько вариантов |
|||
# `makefile Makefile *.mk' |
|
||
case "$prev" in |
|
||
esac-*f) |
COMPREPLY=( $(compgen -f $cur ) ); return 0;; |
||
# Если запрошены возможные ключи, то вернуть ключи posix |
|||
case "$cur" in |
|
||
esac-) |
COMPREPLY=(-e -f -i -k -n -p -q -r -S -s -t); return 0;; |
# попробовать передать make `makefile' перед тем как попробовать передать `Makefile' if [ -f makefile ]; then
mdef=makefile
elif [ -f Makefile ]; then elsemdef=Makefile
436
mdef=*.mk
fi
# прежде чем просмотреть "цели", убедиться, что имя makefile было задано
# ключом -f
for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do if [[ ${COMP_WORDS[i]} == -*f ]]; then
donefi
eval makef=${COMP_WORDS[i+1]} break
[ -z "$makef" ] && makef=$mdef
# Если задан шаблон поиска, то ограничиться |
|
|
# этим шаблоном |
|
|
if [ -n "$2" ]; then gcmd='grep "^$2"' ; else gcmd=cat ; fi |
|
|
# если мы не желаем использовать *.mk, то необходимо убрать cat и использовать |
||
# test -f $makef с перенаправлением ввода |
][^=]*:/ {print $1}' | tr |
|
COMPREPLY=( $(cat $makef 2>/dev/null | awk 'BEGIN {FS=":"} /^[^.# |
||
-s ' ' '\012' | sort -u | eval $gcmd ) ) |
|
|
} |
|
|
complete -F _make_targets -X '+($*|*.[cho])' make gmake pmake |
|
|
# cvs(1) completion |
|
|
_cvs () |
|
|
{ |
cur prev |
|
local |
|
|
COMPREPLY=() |
|
|
cur=${COMP_WORDS[COMP_CWORD]} |
|
|
prev=${COMP_WORDS[COMP_CWORD-1]} |
|
|
if [ $COMP_CWORD -eq 1 ] || [ "${prev:0:1}" = "-" ]; then |
|
|
COMPREPLY=( $( compgen -W 'add admin checkout commit diff \ |
|
|
export history import log rdiff release remove rtag status \ |
|
|
tag update' $cur )) |
|
|
elseCOMPREPLY=( $( compgen -f $cur )) |
|
|
fi |
|
|
return 0 |
|
|
} |
|
|
complete -F _cvs cvs |
|
|
_killall |
() |
|
{ |
cur prev |
|
local |
|
|
COMPREPLY=() |
|
|
cur=${COMP_WORDS[COMP_CWORD]} |
|
|
# получить список процессов |
|
|
COMPREPLY=( $( /usr/bin/ps -u $USER -o comm | \ |
|
|
sed -e '1,1d' -e 's#[]\[]##g' -e 's#^.*/##'| \ |
|
|
awk '{if ($0 ~ /^'$cur'/) print $0}' )) |
|
|
return 0 |
|
|
} |
|
|
complete |
-F _killall killall killps |
|
#Функция обработки мета-команд
#В настоящее время недостаточно отказоустойчива (например, mount и umount
#обрабатываются некорректно), но все еще актуальна. Автор Ian McDonald, изменена мной.
_my_command()
{
local cur func cline cspec
COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]}
if [ $COMP_CWORD = 1 ]; then COMPREPLY=( $( compgen -c $cur ) )
elif complete -p ${COMP_WORDS[1]} &>/dev/null; then cspec=$( complete -p ${COMP_WORDS[1]} )
if [ "${cspec%%-F *}" != "${cspec}" ]; then
# complete -F <function>
#
437