Speaking UNIX: Секретные рецепты продвинутых пользователей UNIX

Вам не нужно взламывать офис, чтобы раскрыть секреты продвинутых пользователей UNIX®- у нас есть информатор, который уже выведал эти секреты.

Мартин Стрейчер (Martin Streicher), независимый web-разработчик, IBM

Мартин Стрейчер (Martin Streicher) (Jeff J. Li) - фотографияМартин Стрейчер (Martin Streicher) - независимый web-разработчик и бывший главный редактор Linux Magazine. Он имеет степень магистра компьютерных наук Университета Пардью (Purdue University) и занимается программированием в UNIX-подобных операционных системах с 1986 года. Он коллекционирует предметы искусства и игрушки.


developerWorks Contributing author
        level

18.07.2011

Вам хотите знать, почему я надел солнцезащитные очки, фальшивые усы и бейсбольную кепку (с логотипом команды по кёрлингу The Floating Stones)? Я скрываюсь. Я ускользнул от черных вертолетов на дистанционном управлении, мстительных системных администраторов и соединенных сил множества злодеев, чтобы рассказать вам о самых тщательно скрываемых секретах продвинутых пользователей UNIX®.

Сохраняем переменные окружения

Большинство пользователей UNIX хранят свои настройки в стартовых файлах оболочки, таких как .bashrc (для Bash) и .zshrc (для Z), чтобы каждый раз при входе в систему воссоздавать свое рабочее окружение. В стартовых файлах можно создавать алиасы, задавать параметры оболочки, создавать функции и задавать переменные окружения. Среди важных переменных окружения стоит отметить переменные HOME (которая указывает на домашнюю директорию), PATH (в которой перечислены все директории, в которых система будет искать приложения) и MANPATH (в которой перечислены все директории, в которых система будет искать страницы справочника man). Чтобы посмотреть, какие переменные заданы в вашей оболочке, выполните команду printenv. Полный список доступных переменных окружения можно выяснить на соответствующей странице man вашей оболочки.

Также как и оболочку, с помощью переменных окружения можно настроить под себя и множество других UNIX-приложений. Например, подсистема Java™ требует, чтобы была задана переменная окружения JAVA_HOME, указывающая на корневую директорию среды выполнения Java. Аналогичным образом набор утилит Amazon Web Services (AWS) требует, чтобы переменная AWS_CREDENTIAL_FILE указывала на файл с корректными именем пользователя и паролем для ключа идентификации. Отдельные приложения также используют переменные окружения. Как узнать, какие переменные окружения можно использовать? К счастью, вам не нужно что-либо взламывать или куда-то проникать; вместо этого просто проконсультируйтесь со страницей man используемой утилиты и поищите в ней раздел с заголовком "Environment Variables"

Например, программа просмотра текстовых файлов less использует несколько полезных переменных окружения:

  • В переменной окружения LESS хранятся параметры командной строки, с которыми следует запускать программу. Она позволяет сократить количество нажатий клавиш для запуска программы. Например, если вы читаете много файлов журналов, поместите в стартовый файл оболочки следующие строки:
    export LESS='--RAW-CONTROL-CHARACTERS --squeeze-lines --ignore-case'

    Эти параметры интерпретируют управляющие символы (которые обычно регулируют подсветку синтаксиса), сокращают соответственно последовательности пустых строк до одной строки и ведут поиск и независимо от регистра символа. Если вы работаете с кодом, то попробуйте следующие параметры:

    export LESS='--LINE-NUMBERS --quit-if-one-screen --quit-on-intr'
  • Переменная окружения с именем LESSKEY указывает на файл со списком горячих клавиш. С помощью горячих клавиш можно настроить поведение less так, чтобы оно, например, соответствовало поведению другой программы просмотра или редактирования файлов.
  • Также как и оболочка, less может хранить историю команд, доступную для использования в последующих запусках. Задайте в переменных окружения LESSHISTFILE и LESSHISTSIZE файл, в который будут соответственно записываться команды и максимальное количество запоминаемых команд.

Еще одним хорошим примером применения переменных окружения является набор компиляторов GNU (GNU Compiler Collection, GCC). GCC определяет множество переменных окружения, позволяющих настроить его работу. В переменной LIBRARY_PATH, как следует из ее имени, перечисляются пути, в которых следует искать библиотеки для компоновки. Переменная COMPILER_PATH работает аналогично переменной PATH в оболочке – она используется для поиска подпрограмм, используемых в процессе компиляции.

Если вы пишете код и собираете исполняемые файлы только для одной платформы, то, возможно, вам никогда не понадобятся эти переменные окружения. Однако если вы компилируете один и тот же код для нескольких платформ, то эти переменные будут очень важны для указания путей к заголовочным файлам и библиотекам каждой платформы. Можно использовать для одной системы один набор значений переменных окружения, а для другой системы – другой набор.

Можно позаимствовать этот прием у GCC: Поддерживайте для приложения несколько наборов переменных окружения и переключайтесь от одного набора к другому в зависимости от выполняемой работы. Один из подходов – это хранить файл инициализации окружения в директории каждого проекта и выполнять (source) его при необходимости. Например, многие разработчики на Ruby используют такое решение для переключения между версиями Ruby. При необходимости перейти с одной версии на другую они изменяют переменные окружения PATH, GEM_HOME и GEM_PATH.


Используем dot-файлы

Наряду с переменными окружения многие Linux® и UNIX приложения используют так называемые dot-файлы, т.е. небольшие файлы, имена которых начинаются с точки. Эти файлы используются для настройки поведения приложения. Однако в отличие от переменных окружения, позволяющих задать значение флага или передать относительно маленький объем информации, dot-файл может быть куда более объемным и сложным. В этих файлах может использоваться специальный правила синтаксиса или даже свой собственный язык программирования. dot-файлы – это удобное место для хранения параметров и настроек, так как (согласно традициям UNIX) файлы, имена которых начинаются с точки, не отображаются по умолчанию в списке содержимого директории. (Используйте команду ls –a, чтобы увидеть эти так называемые скрытые файлы.) В остальном, если не считать специального имени, dot-файл представляет собой обычный текстовый файл.

Dot-файлы обычно располагаются в домашней директории, однако некоторые программы также ищут dot-файлы в текущей рабочей директории. Если приложение поддерживает более одного dot-файла, программа обычно применяет правила старшинства, по которым она будет отдавать предпочтения одному файлу вместо другого. В общем случае "локальный" dot-файл — находящийся в текущей рабочей директории — имеет самый высокий приоритет, за ним следует файл, находящийся в домашней директории, а за ним – общесистемный конфигурационный файл. Может не быть ни одного из этих файлов, может быть один из них или все. В зависимости от реализации, приложение может воспринимать их как взаимно исключающие, либо дополняющие друг друга. В первом случае будет действовать только первый найденный в цепочке dot-файл. Во втором случае окончательная конфигурация может определяться каскадом, либо каким-либо образом согласовываться.

Примером простого dot-файла является файл управляющих клавиш less: $HOME/.lesskey. Строки этого файла представляет собой пары (сочетания клавиш команды), которые выглядят примерно так:

\r        forw-line
\n        forw-line
e         forw-line
j         forw-line
^E        forw-line
^N        forw-line
k         back-line
y         back-line
^Y        back-line

Примером сложного dot-файла является файл программы fetchmail. Эта утилита принимает электронные письма из множества удаленных источников и доставляет их локально. Работа этой утилиты контролируется исключительно с помощью файла $HOME/.fetchmailrc (см. его многочисленные параметры на странице man). cron, git, vi и многие другие команды также имеют свои dot-файлы. Чтобы узнать, что можно сконфигурировать в dot-файле, обращайтесь к странице man приложения. Некоторые dot-файлы настолько обширны, что удостоены отдельной man-страницы, например crontab.


Тссс . . . тайны SSH

Secure Shell (SSH) – это обширная подсистема, позволяющая безопасно заходить на удаленные системы, копировать файлы и настраивать туннели через межсетевые экраны. Так как SSH – это подсистема, то она предлагает множество параметров для настройки и упрощения работы. На самом деле SSH предоставляет целую "dot-директорию " конфигурационных данных, которая имеет имя $HOME/.ssh. (Ваша директория .ssh должна иметь режим доступа 600, чтобы исключить возможность доступа к ней других пользователей. Режим доступа, отличный от 600, может повлиять на правильную работу подсистемы.) Например, в файле $HOME/.ssh/config можно определить множество сокращений, в том числе псевдонимы для имен машин, контролировать доступ к отдельным машинам и так далее.

Вот типичный блок файла $HOME/.ssh/config, в котором настраивается работа SSH с определенной машиной:

Host worker
HostName worker.example.com
IdentityFile ~/.ssh/id_rsa_worker
User joeuser

В каждом блоке файла ~/.ssh/config конфигурируется одна или несколько машин. Блоки следует отделять друг от друга пустой строкой. В этом блоке используется четыре параметра: Host, HostName, IdentityFile и User. Host задает псевдоним для машины, указанной в параметре HostName. Псевдоним позволяет набирать ssh worker вместо ssh worker.example.com. Далее, параметры IdentityFile и Useroptions сообщают, каким образом можно зайти на машину worker. Первый параметр указывает на закрытый ключ, который следует использовать при работе с данной машиной, а во втором параметре задается имя пользователя. Таким образом, данный блок является эквивалентом команды:

ssh joeuser@worker.example.com -i ~/.ssh/id_rsa_worker

Мощным, но малоизвестным параметром является ControlMaster. Если он задан, то несколько сессий SSH с одной и той же машины будут совместно использовать одно соединение. После установления первого соединения все последующие соединения уже не будут требовать ввести имя пользователя и пароль. Это освобождает вас от рутинного ввода пароля каждый раз при соединении с одной и той же машиной. Параметр ControlMaster настолько удобен, что вы, вероятно, захотите его включить для всех машин. Это можно довольно легко сделать, воспользовавшись метасимволом *::

Host *
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p

Как вы, возможно, догадались, блок с пометкой Host * применяется ко всем машинам, даже тем, которые не указаны явно в конфигурационном файле. Согласно параметру ControlMaster auto, система автоматически попытается использовать существующее соединение, а в случае если она его не найдет, то создаст новое. В параметре ControlPath указывается файл, в который будет записываться совместно используемый сокет. %r заменяется именем пользователя на удаленной системе, %h заменяется именем удаленной машины, а %p обозначает порт, используемый для этого соединения. (Также можно использовать строку %l, она заменяется именем локальной машины.) Согласно указанному выше правилу, система будет создавать управляющие сокеты, которые будут иметь имена файлов, выглядящие примерно так:

master-joeuser@worker.example.com:22

Управляющий сокет удаляется при закрытии всех соединений с удаленной машиной. Если вы хотите узнать, с какими машинами вы соединены в данный момент, просто наберите ls ~/.ssh и посмотрите на имя машины в управляющем сокете (%h).

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

$ ssh example.com -L 5000:localhost:3306

Эту команду можно интерпретировать как «Соединись с машиной example.com и создай туннель между портом 5000 на локальной машине и портом 3306 (порт сервера MySQL) на машине с именем 'localhost'». При построении туннеля имя localhost интерпретируется на машине example.com, поэтому localhost обозначает машину example.com. При установлении исходящего туннеля, формально называемого локальным перенаправлением, локальные клиенты могут соединяться с портом 5000 и работать с сервером MySQL, работающим на машине example.com.

Общая форма создания туннелей выглядит так:

$ ssh proxyhostlocalport:targethost:targetport

Здесь proxyhost обозначает машину, с которой вы можете соединиться по SSH, имеющую сетевое соединение (не по SSH) с машиной targethost. Порт localport - это непривилегированный порт (любой свободный порт с номером выше, чем 1024) на вашей локальной системе, а targetport – это порт сервиса, с которым вы хотите установить соединение.

Предыдущая команда создает туннель, исходящий с вашей машины во внешний мир. Также можно использовать SSH для создания входящих туннелей, позволяющих соединиться извне внешнего мира с вашей локальной системой. Общая форма создания входящего туннеля выглядит так:

$ ssh user@proxyhost -R proxyport:targethosttargetport

При установлении входящего туннеля, формально называемого удаленное перенаправление, параметры proxyhost и targethost меняются ролями: целевой машиной является ваша локльная машина, а прокси – это удаленная машина. Параметр user – это ваше имя пользователя на прокси. Например, входящий туннель можно создать так:

$ ssh joe@example.com -R 8080:localhost:80

Команду можно интерпретировать следующим образом: "зайди на машину example.com с именем пользователя joe и соедини удаленный порт 8080 с локальным портом 80". Эта команда создает для пользователей на машине example.com туннель на машину локальную машину. Удаленный пользователь может обратиться к порту 8080, чтобы соединиться с Web-сервером на локальной машине.

Помимо параметров -L и -R для локального и удаленного перенаправления соответственно, SSH предоставляет параметр –D, создающий HTTP-прокси на удаленной машине. С синтаксисом его использования можно ознакомиться на man-странице SSH.


Переписываем историю

Если вы много работаете в командной строке, то запись истории работы в оболочке можно сохранить вам много времени и избавить от набора лишних символов. Однако использование истории команд без дополнительной настройки иметт есть несколько минусов. В истории хранятся дубликаты команд, и несколько экземпляров оболочки могут влиять на историю друг друга. И то, и другое можно легко устранить. Добавьте в ваш файл .bashrc две следующие строки:

export HISTCONTROL=ignoreboth
shopt -s histappend

Первая строка удаляет из истории оболочки последовательные дубликаты команд. Если вы хотите удалить все дубликаты команд, независимо от того, выполнялись они последовательно или нет, то поменяйте значение этой переменной ignoreboth на erasedups. Вторая строка предписывает сохранять вашу историю работы в оболочке в файле истории при выходе из оболочки. По умолчанию файл истории оболочки Bash называется ~/~/.bash_history (да это dot-файл). Его местоположение можно изменить, задав значение (да, опять) переменной окружения HISTFILE. Если вы хотите хранить последние 10 000 команд в файле истории размером 100 000 записей, добавьте в ваш стартовый файл оболочки следующую строку export HISTSIZE=10000 HISTFILESIZE=100000. Для просмотра истории оболочки выполните в оболочке команду history.

Полезность истории команд была бы сомнительна, если бы из нее нельзя было что-нибудь вспомнить. Именно для этого предназначен оператор оболочки !:

  • !! полностью повторяет последнюю команду.
  • !:0 обозначает имя предыдущей команды.
  • !^ обозначает первый аргумент предыдущей команды. !:2, !:3 и т.д. обозначают второй, третий и т.д. аргументы. !$ обозначает последний аргумент предыдущей команды.
  • !* обозначает все аргументы последней команды, за исключением имени команды.
  • !n обозначает команду, записанную в истории под номером n.
  • !handle обозначает последнюю команду, начинающуюся со строки символов, указанную в handle. Например, !ca обозначает последнюю команду, начинающуюся с символов ca, допустим cat README.
  • !?handle обозначает последнюю команду, содержащую строку символов, указанную в handle. Например, !?READ также может обозначать команду cat README.
  • ^original^substitution заменяет первое вхождение строки original строкой substitution. Например, если предыдущей командой является cat README, команда ^README^license.txt обозначает команду cat license.txt.
  • !:gs/original/substitution заменяет все вхождения строки original на substitution. (!:gs обозначает "global substitution", глобальная подстановка).
  • !-2 обозначает предпоследнюю команду, !-3 обозначает команду, предшествовавшую предпоследней и т.д.

Эти выражения можно соединять в загадочные последовательности, например !-2:0 -R !^ !-3:2. Эта последовательность обозначает имя предыдущей команды, за которым следует -R, первый аргумент предыдущей команды и второй аргумент команды, предшествовавшей предпоследней. Чтобы такие команды было легче читать, можно раскрывать «исторические ссылки» уже при вводе команды. Наберите в оболочке команду bind Space:magic-space или добавьте ее в стартовый файл, чтобы привязать клавишу пробел к функции magic-space. Эта функция выполняет подстановки из истории непосредственно в строке ввода команды.


Распаковываем архивы

В сети Internet имеется так много всего, и вы, вероятно, каждый день загружаете на свою машину десятки архивов. И вполне вероятно, что все эти файлы упакованы в различных форматах — тут ZIP-файл, там RAR-файл, изрядное количество tar-архивов и т.д. Каждый раз приходится вспоминать, каким образом можно распаковать тот или иной архив. Почему бы не объединить все эти задачи в одну команду? Приведенная ниже функция часто встречается во многих примерах dot-файлов:

ex () {
  if [ -f $1 ] ; then
    case $1 in
      *.tar.bz2)   tar xjf $1        ;;
      *.tar.gz)    tar xzf $1     ;;
      *.bz2)       bunzip2 $1       ;;
      *.rar)       rar x $1     ;;
      *.gz)        gunzip $1     ;;
      *.tar)       tar xf $1        ;;
      *.tbz2)      tar xjf $1      ;;
      *.tgz)       tar xzf $1       ;;
      *.zip)       unzip $1     ;;
      *.Z)         uncompress $1  ;;
      *.7z)        7z x $1    ;;
      *)           echo "'$1' cannot be extracted via extract()" ;;
    esac
  else
    echo "'$1' is not a valid file"
  fi
}

Функция ex может распаковывать 11 форматов файлов, также ее можно расширить, если вы работаете с другими архивами. Определите ее единожды, например, в стартовом файле оболочки, и вы сможете открывать архивы командой ex somefile, где файл somefile имеет одно из указанных в команде расширений:

$ ls
source
$ tar czf source.tgz source
$ ls -1
source
source.tgz
$ rm -rf source
$ ex source.tgz
$ ls -1
source
source.tgz

Кстати, если вы вдруг потеряли из виду какой-нибудь файл, который вы загрузили сегодня, найдите его с помощью команды find:

$ find ~ -type f -mtime 0

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


Многие другие секреты

Существует множество других секретов, которыми эксперты могут поделиться с вами. Поищите в Web по ключевым словам "shell auto-complete" чтобы узнать больше об автодополнении (возможности дополнения набираемой команды в зависимости от контекста). Также поищите по ключевым словам "shell prompts" чтобы узнать, как настроить ваше приглашение для работы в оболочке. Можно сделать его цветным, можно показывать в нем текущую рабочую директорию или текущую ветвь Git; также можно показывать текущий номер в истории команд — удобная подсказка, если вы много работаете с историей. Поищите на Github по словам «dot files» рабочие примеры такой настройки. Многие эксперты размещают на Github свои настройки оболочки.

Теперь, если вы меня извините, я поищу свой парик и автозагар. Не так то просто скрываться, когда напоминает Граучо Маркса.

Ресурсы

Научиться

  • Оригинал статьи - Speaking UNIX: The best-kept secrets of UNIX power users (developerWorks, май 2010 г.).
  • dotfiles.org: здесь вы найдете большую онлайновую коллекцию dot-файлов.
  • Узнайте больше об оболочках UNIX из этой статьи Википедии.
  • На странице проекта GNU Bash shell можно найти документацию и исходный код этой оболочки.
  • На сайте developerWorks в разделе AIX и UNIX вы всегда сможете найти огромное количество информации, касающейся всех аспектов администрирования систем AIX.
  • Начинаете работать с AIX и UNIX? Посетите раздел AIX и UNIX для новичков чтобы узнать больше об AIX и UNIX.
  • В магазине технической литературы можно найти книги по этой и другим тематикам.

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

  • На Github размещены тысячи Git-репозиториев, в том числе персональные dot-файлы многих пользователей-экспертов. Эти файлы можно найти, поискав по ключевым словам "dot files". (Вы можете больше узнать о Git в онлайновых руководствах Github.)

Обсудить

Комментарии

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=733514
ArticleTitle=Speaking UNIX: Секретные рецепты продвинутых пользователей UNIX
publish-date=07182011