20 июл. 2000 г.

Язык bash часть 8

Язык командного интерпретатора bash. Part 7. «Функции»


Вот и наступил черёд седьмого топика цикла о языке командного интерпретатора bash. В некотором роде число «7» является везучим, как говорят в народе. Надеюсь, и меня не обойдёт данная примета.
Сегодня будут разобраны такие конструкции языка bash, как функции. Надеюсь, тебе не нужно рассказывать о том, что такое функция и для чего она применяется, ведь её смысл эквивалентен понятию функции из любого другого языка программирования. Объём информации сегодня не большой, поэтому пост имеет довольно скромные размеры. Итак, приступим к непосредственному разбору функций в bash.
Общий синтаксис оператора определения функции:

[function] имя_функции () {
список_комманд
}

Кроме K&R-стиля также применим BSD-стиль:

[function] имя_функции ()
{
список_комманд
}

Вызвать функцию можно в любом месте сценария, но перед этим она должна быть объявлена. Вызов осуществляется указанием имени функции в тексте скрипта.

#определение функции
func1 () {
  echo "Hello."
} #вызов функции
funс1

Функции принимают входные аргументы и возвращают код завершения. Доступ к входным аргументам осуществляется через позиционные параметры. Позиционный параметр 0 содержит имя функции. Внутри функции доступны локальные переменные сценария. Приведу пример:
param1=Hello
func2 () {
param2=${1-$param1}
echo "param2 = $param2"
}

Теперь пример с аргументами:
func3 () {
if [ "$1" ]
then
echo "Аргумент #1: \"$1\".-"
fi
if [ "$2" ]
then
echo "Аргумент #2: \"$2\".-"
fi
}
func3 #вызов функции без аргументов
func3 arg1 #вызов функции с одним аргументом
func3 arg1 arg2 #вызов функции с двумя аргументами

Если при выполнении функции произошла ошибка, происходит завершение выполнения функции с ненулевым кодом возврата. Код завершения можно задавать явно с помощью команды return. Код завершения в сценарии может быть получен через переменную $? и доступен до выполнения следующей команды.
Возможности bash позволяют переопределить stdin для функции, чтобы получать входные данные из файла. Для этого служит конструкция:

имя_функции ()
{
список_команд
} < файл
Также возмож
ен следующий вариант:
имя_функции ()
{
{
список_команд
} < файл
}
==========Добавка из коментов=====================
Пример1
Часто вижу линуксойдов, которые постоянно (когда хотят обратится к какому-то файлу) переходят в директорию(cd /home), затем смотрят её содержимое (ls), затем переходят дальше (cd /home/aonick), опять (ls) и тд… до достижения файла — для них:


lcd(){
  echo "Директория: $1"
  cd $1 && ls}
После этого переходить в нужную директорию можно так:
lcd /home
это команда и в директорию перейдет и сразу содержимое покажет.

Пример 2
Так как функция выполняется в той же сессии (в отличии от скрипта) — удобно например для команд настраивать автозаполнение по Тab-клавиши, напимер для команды rpm чтобы дописывал из списка установленных пакетов:

_rpm-refresh(){ complete -W "$(rpm -qa) -ivh -ql -qi" rpm; }

После этого — каждый раз когда запускаю функцию:
_rpm-refresh
обновляется список аргументов которые предлагаются по нажатию Tab.
И пользуясь командой rpm уже так, например:

rpm -ql apach<i><Нажимаю  дважды Tab></i>
и вижу список установленных пакетов начинающихся с «apach»

Дополнение:

Функция задается только в текущей сессии и после закрытия терминал про неё система забудет. Чтобы навеки-вечные задать своему пользователю функцию — её прописывают в файл ".bashrc" в домашней директории пользователя.