Инструментарий системного администратора: Стандартизация инструментов командной строки UNIX

Здесь рассматриваются методы стандартизации интерфейса для упрощения переключения между различными системами UNIX®. Если вы используете несколько систем UNIX, особенно в разнородной среде, то крайне усложняется переключение между средами и выполнение различных операций с учетом всех особенностей систем. Данная статья не описывает конкретные отличия, но в ней объясняется, как при помощи функций-оберток (wrappers) обеспечить совместимость и стандартизацию среды.

Мартин Браун, внештатный автор, консультант

Мартин Браун (Martin Brown) пишет статьи уже более семи лет. Он является автором многочисленных книг и статей по различным темам. Его квалификация охватывает множество платформ и языков разработки - Perl, Python, Java™, JavaScript, Basic, Pascal, Modula-2, C, C++, Rebol, Gawk, Shellscript, Windows®, Solaris, Linux, BeOS, Mac OS X и т.д., а также Web-программирование, системное управление и интеграция. Мартин является внутренним экспертом (SME) компании Microsoft® и регулярно пишет для ServerWatch.com, LinuxToday.com и IBM developerWorks. Он также принимает участие в блогах Computerworld, The Apple Blog и на других сайтах. Связаться с ним можно через его Web-сайт.



04.12.2007

Об этой серии статей

Обычный администратор UNIX® использует ограниченный набор утилит, приемов и систем для максимального упрощения администрирования. Для упрощения различных процессов используются стандартные утилиты UNIX, последовательности действий с помощью командной строки и скрипты. Некоторые из этих инструментов входят в операционную систему, но большинство приемов основаны на многолетнем опыте и стремлении администраторов облегчить себе жизнь. Данная серия статей посвящена тому, как наиболее эффективно использовать в различных средах UNIX имеющиеся инструменты, включая методы упрощения администрирования в разнородной среде.


Различия и проблемы

Если в компании используется несколько UNIX-хостов, особенно хостов, на которых установлены разные варианты UNIX (Berkeley Software Distribution (BSD), UNIX System Release 4 (VSVR4) и так далее, или различные версии одного варианта UNIX, то скорей всего системному администратору приходится тратить немало времени на изучение отличий этих систем друг от друга.

Например, рассмотрим команду ps. Она запускается с разными опциями командной строки для UNIX-серверов BSD и для UNIX-серверов, основанных на SVR4 (для более полной информации см. Инструментарий Системного Администрирования: Приемы администрирования). Также существуют более значительные различия между платформами. Иногда это даже разное название одной и той же команды; команда, которая в Linux® называется adduser, в Solaris называется useradd.

Существует несколько путей для обеспечения стандартизации:

  • Можно выбрать стандартизацию на основной платформе, например Solaris, и создать функции-обертки (wrappers) для аналогичных команд на других платформах, которые соответствовали бы стандартам Solaris.
  • Можно выбрать стандартизацию набора команд, которые обеспечивают наилучшее выполнение конкретных заданий, выбирая команды по опыту системного администратора, и создать функции-обертки для тех команд, которые не реализованы на конкретной платформе.
  • " Можно создать свой собственный набор скриптов для конкретных задач, включая замену стандартных инструментов (таких как ls, ps и других), которые бы выдавали требуемую информацию. Однако необходимо помнить, что если эти скрипты будут потеряны, то уже нельзя будет воспользоваться оригиналами команд.

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

  • Псевдонимы (aliases) -- данное решение поддерживается только некоторыми командными оболочками (shells). Это простой метод для превращения заданной строковой последовательности в конкретную команду.
  • Функции командной оболочки (shell-функции) -- данное решение поддерживается большинством разновидностей современных командных оболочек. Функции командной оболочки дают вам возможность создавать более сложные последовательности, но так как они функционируют как встроенные, их лучше использовать в случаях, когда различия сравнительно невелики.
  • Скрипты командной оболочки (shell-скрипты) -- если функция-обертка, которую создает администратор, получается особенно сложным, то лучше использовать скрипты. Можно использовать скрипт командной оболочки, который запускается вместо команды-оригинала. Применение скрипта командной оболочки вместо команды дает больше возможностей и даже позволяет полностью заменить команды на скрипты командной оболочки.

Рассмотрим каждое возможное решение и некоторые примеры команд, которые можно эмулировать при его помощи.


Использование псевдонимов

Псевдонимы, поддерживаемые в реализациях командных оболочек Korn (ksh), Bourne-Again SHell (bash), TENEX C shell (tcsh) и Z shell (zsh), - это самое простое решение если нужно установить специфические опции для команды и в то же время обеспечить поддержку других опций. Псевдонимы полностью оправдывают свое название: можно создать для команды псевдоним, который при запуске будет работать так же, как и сама команда, или же можно создать псевдоним, у которого будут какие-то дополнительные опции. Расширенная функциональность псевдонимов зависит от того, что вводится в расширении взятой за основу команды.

Например, типичным псевдонимом является команда ll, которая работает как эквивалент ls -l (ll часто называют длинным листингом). Каждый раз, когда пользователь печатает ll, команда сразу же заменяется ее расширенным вариантом, поэтому также $ ll a* перед выполнением расширяется до $ ls -l a*.

Применение опций командной строки также не изменяется, другими словами $ ll -a расширяется до $ ls -l -a.

Также можно создать псевдоним для существующей команды; у меня, например, опция -F добавлена ко всем командам ls, так что $ ls расширяется до $ ls -F.

Чтобы создать псевдоним, используйте встроенное shell-выражение alias, указывая в кавычках нужное расширение. Например, для того, чтобы создать расширение ll, о котором более подробно говорилось ранее, используйте $ alias ll='ls -l'.

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

Хорошим примером является команда ps, которая отличается на UNIX-хостах SVR4 и BSD. В первой статье данной серии, см. Инструментарий Системного Администрирования: Приемы администрирования объясняется, как использовать опции ps, чтобы получить аналогичные листинги. Можно использовать псевдоним для этой команды, не меняя при этом способность команды или ее псевдонимов поддерживать дополнительные опции. Например, в системе BSD, вы бы могли создать псевдоним, как это сделано в листинге 1.

Листинг 1. Определение псевдонима на BSD
$ alias ps='ps -o pid,ppid,command'

При работе на хосте SVR4 вы бы могли создать псевдоним, как это сделано в листинге 2.

Листинг 2. Определение псевдонима на SVR4
$ alias ps='ps -opid,ppid,cmd

Теперь у вас есть стандартный вывод ps с ограничениями, специфичными для каждой из двух систем. Как и раньше, можно продолжать использовать дополнительные опции, например, запрос через опцию -A перечня всех процессов на обеих платформах, где установлен псевдоним. Пример результата такого запроса - листинг 3 на BSD (в данном случае для Mac OS X).

Листинг 3. Использование опции -A на BSD
$ ps -A
  PID  PPID COMMAND
    1     0 /sbin/launchd
   23     1 /sbin/dynamic_pager -F /private/var/vm/swapfile
   27     1 kextd
   32     1 /usr/sbin/KernelEventAgent
   33     1 /usr/sbin/mDNSResponder -launchdaemon
   34     1 /usr/sbin/netinfod -s local
   35     1 /usr/sbin/syslogd
   36     1 /usr/sbin/cron
   37     1 /usr/sbin/configd
   38     1 /usr/sbin/coreaudiod
   39     1 /usr/sbin/diskarbitrationd
...

Система SVR4 (Gentoo Linux хост) покажет вам ряд колонок, см. листинг 4.

Листинг 4. Использование опции -A на SVR4
$ ps -A
  PID  PPID CMD
    1     0 init [3]         
    2     1 [migration/0]
    3     1 [ksoftirqd/0]
    4     1 [watchdog/0]
    5     1 [migration/1]
    6     1 [ksoftirqd/1]
    7     1 [watchdog/1]
    8     1 [events/0]
    9     1 [events/1]
   10     1 [khelper]
   11     1 [kthread]
   14    11 [kblockd/0]
   15    11 [kblockd/1]
   16    11 [kacpid]
...

Существует и способ применения псевдонимов, альтернативный приведенным далее в этой статье скриптовым и функциональным решениям. Можно создавать псевдонимы для определенного типа вывода каких-либо команд, которые используют один и тот же метод для предоставления аналогично отформатированного вывода. Например, в случае с ps можно создать псевдоним ps-all для вывода перечня всех процессов, устанавливая расширение для каждой платформы так, как это требуется.

Лучше всего установить данные псевдонимы в скрипте инициализации оболочки, таком, как .ksh, .profile или .bashrc, который исполняется во время входа в систему. В этом случае можно выполнять проверки системы, которые позволяют контролировать то, какие псевдонимы активировать. Если нужно найти глобальное решение, которое работало бы для всех пользователей, то следует разместить определения псевдонимов в общедоступной папке, например, в /etc или /usr/local, и установить скрипты инициализации пользователей так, чтобы им были предоставлены определения псевдонимов.

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


Использование встраиваемых shell-функций

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

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

На платформе Solaris команда killall существует, но она используется как часть процесса выключения для остановки всех процессов. Если случайно вызвать команду killall на хосте Solaris, чтобы остановить все процессы Apache, то это может привести к остановке всей системы!

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

Основной составляющей обсуждаемой команды является способность идентифицировать текущие процессы, выбирать те, которые соответствуют заданной строке, и использовать команду kill для подачи сигнала KILL каждому соответствующему процессу. В командной строке можно достичь эквивалента через набор pipe-ов (каналов) (используя сигнал KILL), как это показано в листинге 5.

Листинг 5. Замена для команды killall
$ ps -ef|grep gcc|awk '{ print $2; }'|xargs kill -9

Ключевыми компонентами команды являются строки, передаваемые grep (в данном случае это строка gcc), и столбец вывода ps, содержащий ID процесса. Приведенный выше пример относится к Solaris и большинству вариантов SVR4 UNIX.

В приведенном примере псевдоним не сработает, поскольку информация, которую нужно вставить в команду, еще не готова, а псевдонимы работают при помощи расширения. Тем не менее, встраиваемая shell-функция отлично для этого подходит.

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

Листинг 6. Определение функции
function NAME()
{
# do stuff here
}

Параметры вызываемой функции в типичном shell-скрипте доступны как $1, $2, и т.д. Поэтому можно определить функцию, которая выполняет передачу таких же сигналов строкового типа, как и killall (см. листинг 7).

Листинг 7. Определение функции, которая выполняет такую же передачу сигналов, как и killall
function killall()
{
    ps -ef|grep $1|awk '{ print $2; }'|xargs kill -9
}

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

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

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


Использование скриптов

Самый простой и совместимый с большинством систем способ создать устойчивую среду - это создать shell-скрипты, которые могут использоваться как "обертки" для настоящих команд, отвечающих за различные опции и настройки, которые вы хотели бы задействовать.

Например, команды useradd и adduser поддерживают одинаковые односимвольные опции командной строки, когда настраиваются параметры, такие как ID пользователя или принадлежность групп; так $ adduser -u 1000 -G sales,marketing mcbrown в Linux эквивалентно $ useradd -u 1000 -G sales,marketing mcbrown в Solaris.

Тем не менее, версия Linux также поддерживает расширенные командные опции, например, --uid и --groups эквивалентны указанным выше опциям командной строки. Они не поддерживаются на Solaris, но, если вы создадите shell-скрипт с именем adduser, вы сможете эмулировать версию Linux и затем запустить настоящую команду Solaris useradd с подходящими опциями.

Листинг 8 дает образец shell-скрипта, который функционирует как "обертка" либо для команды adduser, либо для команды useradd.

Листинг 8. Образец shell-скрипта, который функционирует как "обертка"
#!/bin/bash
# -*- shell-script -*- 


for i in $*
do
  case $i in
      --uid|-u) OPT_UID=$2; shift 2;;
      --groups|-G) OPT_GROUPS=$2; shift 2;;
      --gid|-g) OPT_GROUP=$2; shift 2;;
      --home-dir|-d) OPT_HOMEDIR=$2; shift 2;;
      --shell|-s) OPT_SHELL=$2;shift 2;;
      --non-unique|-o) OPT_NONUNIQUE=1;shift 2;;
      --comment|-c) OPT_COMMENT=$2;shift 2;;
  esac
done

OPTS=""

if [ -n "$OPT_$HOMEDIR" ]
then
    OPTS="$OPTS -d $OPT_HOMEDIR"
fi

if [ -n "$GROUP" ]
then
    OPTS="$OPTS -g $OPT_GROUP"
fi

if [ -n "$OPT_GROUPS" ]
then
    OPTS="$OPTS -G $OPT_GROUPS"
fi

if [ -n "$OPT_SHELL" ]
then
    OPTS="$OPTS -s $OPT_SHELL"
fi

if [ -n "$OPT_UID" ]
then
    OPTS="$OPTS -u $OPT_UID"
fi

if [ -n "$OPT_COMMENT" ]
then
    OPTS="$OPTS -c \"$OPT_COMMENT\""
fi

if [ -n "$OPT_NOUNIQUE" ]
then
    OPTS="$OPTS -o"
fi

CMD=adduser

UNAME=`uname`

case $UNAME in
    Solaris) CMD=useradd;break;;
esac

$CMD $OPTS $*

Ключевым в этом скрипте является оператор цикла foreach, который по очереди обрабатывает аргументы, переданные в командной строке и доступные в $*. Для каждой опции оператор case пытается далее ее идентифицировать, используя либо краткий, либо длинный формат и устанавливая переменную. Переключатель, обеспеченный командной строкой, - это $1. Если за опцией следует какое-либо значение (например, ID пользователя), тогда можно получить к ней доступ через $2. $2 используется для присвоения значения переменной.

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

Когда возможные аргументы идентифицированы и извлечены, все, что остается сделать, - это передать новые опции команде, которая будет использоваться в конечном счете. Поскольку обе команды useradd и adduser поддерживают сокращенную форму записи аргументов, то на этой основе может быть создана новая строка командных опций. Это достигается проверкой, установлена ли соответствующая переменная, и добавлением опции в командную строку. Обратите внимание на использование двойных кавычек, которое гарантирует, что поставленные в кавычки изначальные параметры сохранены и идентифицированы должным образом.

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

Листинг 9. Добавление пользователя
$ adduser.sh --homedir /etc -g wheel --shell /bin/bash -c "New user" mcbrown

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

Если нужно установить этот скрипт с изначальным именем (например, adduser) и поместить это в папку (например, /usr/local/compat), следует убедиться в том, что папка появляется в PATH до того, как появляется папка настоящей команды. Вот пример этого, когда скрипты совместимости помещаются в папку /usr/local/compat: $ PATH=/usr/local/compat:$PATH.


Использование одного исходника

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

Можно использовать один исходник, применяя комбинацию инструментов командной строки и управления потоками оболочки (таких как if или case). Здесь особенно полезны 2 инструмента: тот, который определяет хост (такой как hostname или uname), и тот, который определяет платформу (uname).

Команда uname выводит имя основной операционной системы, например, Linux или Solaris. Например, можно использовать ее в сочетании с выражением case, чтобы выбрать правильные псевдонимы, согласно примерам ps в предыдущем разделе, так, как в листинге 10.

Листинг 10. Вывод команды uname
UNAME='uname'
case "$UNAME" in
FreeBSD|NetBSD|Darwin)
    alias ps='ps -o pid,ppid,command'
    break
    ;;
Solaris|Linux) 
    alias ps='ps -o pid,ppid,cmd'
    break
    ;;
esac

Такой же базовый процесс может использоваться в скрипте для выбора определенной последовательности.

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


Резюме

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

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

Несмотря на очевидные преимущества, важно помнить о том, что если слишком сильно изолироваться от базовой системы, то системный сбой, из-за которого скрипты станут недоступны, создаст очень сложную ситуацию и поэтому лучше использовать расширение или настройку, чем замену.

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


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

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=AIX и UNIX
ArticleID=273043
ArticleTitle=Инструментарий системного администратора: Стандартизация инструментов командной строки UNIX
publish-date=12042007