Список команд функции командного интерпретатора Linux

Как и во многих языках программирования, командный интерпретатор имеет средства структуризации сценариев при помощи функций. Составной именованный список команд, называемый функцией, объявляется при помощи (Bourne-  и POSIX-диалекты) конструкций

name() compound-list

или (Korn-диалект)

function name compound-list

с использованием ключевого слова function, где compound-list — это составной список, например, if, case, for или while. Сформировать составной список из конвейера, простого или условного списка можно при помощи конструкций {list; } или (list), позволяющих выполнить list в том же или в отдельном дочернем процессе интерпретатора.

После объявления функция может быть неоднократно вызвана (как и любая другая внешняя или встроенная команда) с разными фактическими параметрами, значения которых в самой функции доступны при помощи подстановки позиционных параметров.

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

Список пользователей, зарегистрированных в операционной системе

bender@ubuntu:~$ function getusers↵
> {↵
> getent passwd | cut -f 1 -d : | xargs -n1 id↵

}↵

bender@ubuntu:~$ type -a getusers

getusers является функцией

getusers ()

{

getent passwd | cut -f 1 -d : | xargs -n1 id

}

bender@ubuntu:~$ getusers

uid=0(root) gld=0(root) группы=0(root)

uid=1001(finn) gid=1001(finn) группы=1007(candy), 1001(finn)

uid=1002(mike) gid=1002(mike) группы=1002(mike)

uid=1003(iceking) gld=1603(iceking) группы=1003(iceking)

uid=1004(marceline) gid=1004(marceline) группы=1004(marceline)

uid=1005(bubblegun) gid=1005(bubblegum) группы=1007(candy),1005(bubblegum)

uid=1006(fitz) gid=1008(fitz) группы=27(sudo),1008(fitz)

uid=1007(skillet) gid=1009(skillet) группы=1009(skillet)

uid=1008(bender) gid=1010(bender) группы=1010(bender)

В листинге ниже объявляется функция, являющаяся универсальным экстрактором «архивов». Сначала при помощи «красивой» формы [ команды test определяется наличие файла (-f), путевое имя которого будет передано первым фактическим параметром при вызове функции.

Затем, если заданный файл найден, при помощи множественного ветвления и шаблонов, «примеряемых» к имени заданного файла, определяется и выполняется в соответствующей ветви команда распаковки tar, gunzip, bunzip2, rar, unzip, uncompress или 7z. При запуске функции в режиме трассировки видно, как работает передача аргументов в функцию, как выполняются списки ветвления и множественного ветвления.

Универсальный экстрактор архивов

bender@ubuntu:~$ extract ()↵
> if [ -f $1 ] ↵
> then ↵
> case $1 шn ↵
> *.tar) tar xf $1;; ↵
> *.tar.bz2|*.tbz2) tar xjf $1;; ↵
> *.tar.gz|*.tgz) tar xzf $1;; ↵
> *.gz) gunzip $1;; ↵
> *.bz2) bunzip2 $1;;↵

> *.rar) rar x     $1;; ↵
> *.zip) unzip    $1;; ↵
> *.Z) uncompress $1;; ↵
> *.7z|*.iso) 7z X $1;• ↵
*) echo «Неизвестен распаковщик для return 1;; ↵
> esac ↵
> else ↵
£. > echo «‘$1’ не является файлом»; return 1 ↵
> fi
bender@ubuntu:~$ type -a extract

extract является функцией

extract ()
{
}
bender@ubuntu:~$ set -x

bender@ubuntu:~$ extract dvd.iso

+ extract dvd.iso

+ ‘[‘ -f dvd.iso ‘]’

+ case $1 in ,

+ 7z x dvd.iso

7Zip 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18

p7zip Version 9.20 (locale=ru_RU.UTF-8,Utf 16=on,HugeFiles=on,4 CPUs)

Processing archive: dvd.iso

bender@ubuntu:~$ extract /tmp

+ extract /tmp

+'[‘ -f /tmp ’]’

+ echo “\’/tnp’\» не является файлом’

‘/tmp’ не является файлом

+ return 1

bender@ubuntu:~$ extract lynx_2.8.8dev.9-2ubuntu0e.12.04.1_all.deb

} + extract lynx_2.8.8dev.9-2ubuntu0.12.04.1_all.deb

+ ’[‘ -f lynx_2.8.8dev.9-2ubuntu0.12.04.l.all.deb ‘]’

+ case $1 in

* echo ‘Неизвестен распаковщик для ‘\»lynx_2.8.8dev.9.2ubuntu0.12.04.1_all.deb’\»‘

Неизвестен распаковщик для ‘lynx_2.8.8dev.9.2ubuntu0.12.04.1_all.deb’

+ return 1

Объявленные функции, как и переменные, располагаются в оперативной памяти процесса командного интерпретатора, в силу чего их время жизни и область видимости так же ограничиваются процессом их интерпретатора.

В этом смысле объявленные функции практически неотличимы от встроенных команд интерпретатора и могут расцениваться как его «расширения».

Сохранить объявленные функции и присвоенные переменные нельзя, но можно их повторно объявить и присвоить, воспользовавшись инициализационными dot-файлами  интерпретатора, например сценариями .bashrc или .profile.

Добавить комментарий