Использование UNIX, Часть 1: Работа с командной строкой

Создайте бесчисленное множество программ, комбинируя утилиты UNIX между собой

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

Мартин Стрейчер, главный редактор, Linux Magazine

Мартин Стрейчер (Martin Streicher) -- главный редактор журнала Linux Magazine. Он имеет степень магистра компьютерных наук Университета Пардью (Purdue University) и с 1982 занимается программированием на языках Pascal, C, Perl, Java и (с недавнего времени) Ruby в UNIX-подобных операционных системах.



22.10.2007

Знакомство с оболочкой UNIX

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

Например, чтобы перечислить все файлы с уникальными именами в текущем каталоге, вы можете напечатать в оболочке UNIX (shell) следующую строку:

find . -type f -print | sort | uniq

Эта строка последовательно использует три различные утилиты:

  • Утилита find просматривает указанный каталог - в этом случае файловую систему, начинающуюся с . (точки) (условное обозначение для текущего каталога) – и выводит названия всех файлов, которые соответствуют указанному критерию. Параметр –type f указывает утилите find искать только обычные файлы.

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

  • Утилита uniq (сокр. от "unique") сканирует список, сравнивая смежные элементы и удаляя дубликаты из списка. Например, предположим, есть такой список:

    Пример 1. Исходный список
    Groucho
    Groucho
    Chico
    Chico
    Groucho
    Harpo
    Zeppo
    Zeppo

    Утилита uniq сокращает содержимое этого списка до следующего:

    Пример 2. Использование команды uniq
    Groucho
    Chico
    Groucho
    Harpo
    Zeppo

    Однако если бы исходный список изначально был отсортирован (все имена были бы расположены по алфавиту), запуск uniq привел бы к следующим результатам:

    Пример 3. Использование команды uniq
    Chico
    Groucho
    Harpo
    Zeppo

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


Работа с системами ввода / вывода в UNIX

Утилита find всегда принимает на вход содержимое файловой системы, в том случае, если она запущена независимо от других утилит. Однако утилиты sort и uniq получают входные данные от стандартного устройства ввода (stdin). Чаще всего в этом качестве используется клавиатура. Например, вы печатаете строки, содержащие данные, которые вы хотите отсортировать.

По умолчанию find печатает результаты работы на стандартное устройство вывода (stdout). Обычно это консоль вашего терминала. Утилиты sort и uniq также печатают результаты в stdout.

Чтобы проверить работу stdin и stdout, напечатайте следующий текст в вашей консоли (символ % - это приглашение оболочки на ввод команды):

Пример 4. stdin и stdout
% 
sort
mustache
horn
hat
Control-D

Утилита sort считывает из stdin три строки, которые вы напечатали, сортирует их и выводит результат. Рисунок 1 показывает схему работы sort и большинства утилит UNIX, запускаемых из командной строки.

Рисунок 1. Стандартная утилита UNIX запускается из командной строки, считывает данные с stdin и выводит результат в stdout
работа утилиты в командной строке UNIX

Некоторые утилиты, такие как find, не считывают данные из stdin. Вместо этого они получают данные для обработки из различных источников, таких как файловая система или ядро, и выводят результаты в stdout. Чтобы понять, как работает find, посмотрите на рисунок 2.

Рисунок 2. Некоторые утилиты считывают данные из системных ресурсов и выводят результат в stdout
утилита с альтернативным вводом данных

В дополнение к stdin и stdout, команды UNIX могут выводить сообщения об ошибках в специальную систему вывода, которая используется для отладки. Эта система называется – стандартное устройство для вывода ошибок (обычно к нему обращаются как к stderr). На рисунке 3 показана схема работы утилиты, запускаемой из командной строки.

Рисунок 3. Команды UNIX могут выводить ошибки в специальную систему вывода (standard error)
утилита, использующая stderr для вывода ошибок

Как следует из рисунка 3, большинство команд UNIX считывают данные с консоли терминала, выводят на терминал результаты работы и сведения о возникших ошибках. По умолчанию, пока вы не измените конфигурацию, ваш терминал – это источник данных для stdin и пункт назначения для данных из stdout и ошибок из stderr.


Перенаправление данных

Однако вы можете изменить источник данных для stdin и пункты назначения для вывода stdout и stderr. Вы можете заставить stdin считывать данные из файла или c устройства, подключенного к компьютеру, или извлекать данные из сетевого подключения. Точно так же вы можете направить вывод в файл, на устройство или через сетевое подключение. В UNIX любое устройство ввода / вывода можно рассматривать как файл, и использовать для передачи входных данных или вывода результатов.

Изменение источника или пункта назначения обрабатываемых данных называется перенаправлением. Вы можете перенаправить stdin, чтобы считывать данные с файла или другого источника, и вы можете перенаправить по отдельности stdout и stderr, чтобы выводить данные куда-нибудь еще, кроме окна терминала. В большинстве случаев, как в команде find, показанной раньше, вы можете перенаправить ввод или вывод для утилиты, чтобы сформировать входные данные для другой утилиты или принять данные от нее на вход. Для этого существует символ |, обозначающий канал ввода / вывода. Вы можете связывать этапы обработки между собой, используя каналы, отправляя данные из одной команды в следующую команду, подобно подаче воды по трубам.

Рисунок 4 показывает последовательность выполнения следующей команды find . -type f -print | sort | uniq.

Рисунок 4. Схема взаимодействия трех утилит, связанных каналами ввода / вывода
перенаправление ввода / вывода команд в UNIX

Канал вывода stdout команды find становится каналом ввода stdin команды uniq. В свою очередь канал вывода stdout команды uniq подает данные в канал входа stdin команды sort. Наконец, команда sort печатает результаты в свой канал вывода stdout, который выводит информацию на терминал. Канал вывода stderr для вывода ошибок не было перенаправлен, поэтому все три команды печатают сообщения об ошибках на терминал. Сообщения об ошибках этих команд могут сливаться друг с другом, но порядок сообщений будет правильный.

Если потребуется, вы можете продлить канал и перенаправить выход uniq в другую утилиту. Просто присоедините другой канал, чтобы продолжить преобразование. Например, вы можете добавить | less, чтобы выводить результат по страницам, или добавьте | wc -l чтобы подсчитать количество файлов с уникальными именами. Команда wc (сокр. от word count) может считать символы, слова, строки.

Или вы можете использовать символ >, чтобы сохранить результат работы всей последовательности команд в файл (перезаписав его текущее содержимое). Также можно использовать >>, чтобы приписать результаты работы к содержимому файла (если такого файла нет – он будет создан).

Другое полезное перенаправление обозначается символом <. Рисунок 5 показывает, как можно перенаправить stdin, чтобы поток ввода считывал данные из файла. Команда sort считывает список слов из указанного файла и сортирует его по алфавиту.

Рисунок 5. Перенаправление стандартного канала ввода на считывание из файла
перенаправление stdin на считывание из файла

Часто вам требуется собрать данные с stdout и stderr устройств. Например, если вы выполняете объемную задачу по анализу данных, вы, возможно, захотите просмотреть промежуточные результаты и ошибки, которые возникли по ходу работы. Вы можете использовать различные типы перенаправления, чтобы сделать это: |&, >&, >>&, например, создать канал и перенаправить туда stdout и stderr. На рисунке 6 показано, как перенаправить устройства stdout и stderr в общий поток вывода.

Рисунок 6. Сведение каналов stderr и stdout в один поток вывода
сведение каналов stderr и stdout в один поток вывода

Введение в оболочку Z (Z shell)

Большинство современных оболочек UNIX, включая bash - оболочку Борна (Bourne shell) и ksh - оболочку Корна (Korn shell), поддерживают виды перенаправления, упоминавшиеся выше, хотя синтаксис, используемый в этих оболочках, может слегка отличаться. (За дополнительной информацией обращайтесь в документацию по вашей оболочке).

Большинство операторов для перенаправления поддерживаются всеми оболочками UNIX в течение последних 25 лет. Несмотря на это, большая часть оболочек оказались неспособными предложить новые способы использования перенаправления. Например, большинство оболочек могут только перенаправить вход только из одного файла, и вам приходится использовать такую утилиту как tee, чтобы осуществлять вывод сразу в нескольких направлениях. У утилиты tee есть один вход и два выхода. Пример 5 демонстрирует возможности оболочки bash (интерпретатора командной строки).

Пример 5. Использование bash
bash$ ls
tellme
bash$ cat tellme
echo Your current login, working directory, and system are...
whoami
pwd
systemname
bash$ bash < tellme |& tee log
Your current login and working directory are...
strike
/home/strike
bash: systemname: command not found
bash$ ls
tellme log
bash$ cat log
Your current login and working directory are
strike
/home/strike
bash: systemname: command not found

Хотя оболочки UNIX в основном используют для ввода данных клавиатуру, такая оболочка как bash может использовать файл для ввода данных, так как stdin, на самом деле, это тоже файл. В предыдущем примере фрагмент bash < commands заставляет bash выполнить список команд, находящихся в файле tellme. Конструкция |&tee log направляет stdin и stdout bash в утилиту tee, которая печатает данные из канала stdin в stdout и в файл log.

Но что, если вы захотите подать на вход bash более чем один файл? Конструкция cat file1 file2 file3 | bash - это подходящее и, возможно, единственное решение, так как bash не поддерживает такой синтаксис bash < file1 < file2 < file3.

Более того, bash не может направить вывод более чем одному адресату. Например, вы не сможете выполнить такую инструкцию bighairyscript > ~/log | mail -s "Important stuff" team из командной строки bash.

Но относительно новая zsh - оболочка Z (Z shell – см. дополнительную информацию) может обрабатывать сразу несколько входных и выходных перенаправлений из одной командной строки. В примере 6 приведена команда, которая сохраняет stdout в файл, называемый log, и отравляет его по электронной почте.

Пример 6. Работа с оболочкой Z
zsh% bash < tellme > log | mail -s "Who you are" 'whoami'
bash: line 4: systemname: command not found
zsh% <log
Your current login, working directory, and system are...
strike
/home/strike

Фрагмент 'whoami' запускает команду whoami и вставляет результат работы этой команды вместо себя. Такой результат достигается предварительным запуском небольшого фрагмента командной строки перед выполнением остального содержимого командной строки.

Давайте разберем предыдущую команду слева направо. Команда bash создает файл log и отправляет результаты работы команд из файла tellme на адрес электронной почты. Так как поток stderr не перенаправлялся при помощи оператора > или канала, то сообщения об ошибках выводятся в stdout. Команда <log - это другое сокращение Z, работает аналогично команде cat. Так что команда lt;file эквивалента cat file.

Оболочка Z также может обрабатывать более чем одно перенаправление входных данных. Команда cat < file1 < file2 < file3 в оболочке Z эквивалента cat file1 file2 file3. Правда, первый вариант конструкции явно более громоздкий, чем второй, а многократные перенаправления stdout используются куда чаще. Тем не менее, если утилита, которую вам нужно запустить, принимает на вход только один аргумент, возможность оболочки Z по множественному перенаправлению ввода может оказаться полезной.

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


Тонкости при работе с оболочкой

Предлагаем вам несколько полезных советов, которые могут сделать вашу работу в UNIX более продуктивной. Эти команды будут работать во всех оболочках, а не только zsh.

  • Создание полной копии любого каталога, включая символические ссылки, используя команду tar:

    tar cf - /path/to/original |  \
      (mkdir -p /path/to/copy; cd /path/to/copy; tar xvf -)

    Сначала tar архивирует указанный каталог /path/to/original и выводит содержимое архива в stdout, знак переноса (-), используемый с параметром с (создать), направляет вывод в stdout. Команда в круглых скобках - это вложенная оболочка, команды во вложенных оболочках не влияют на работу основной оболочки. Команда mkdir -p создает указанный каталог, включая все промежуточные каталоги, и команда cd переводит оболочку в новый каталог. Вторая команда tar считывает содержимое архива из stdin и извлекает его содержимое в указанный каталог, знак переноса (-) с параметром х (извлечь) заставляет считывать входные данные из stdin.

  • Чтобы сохранить данные из stdout последовательности команд в файл и одновременно просматривать их, используйте конструкцию less -O file. Аргумент -O копирует данные, поступившие по stdin в указанный файл. Например:

    sort /etc/aliases | less -Osorted
  • Если каталог содержит множество файлов ваша оболочка (включая zsh в зависимости от числа файлов и от их имен) может оказаться не способной перечислить все файлы, используя поиск по шаблонам, так как обычно длина содержимого командной строки ограниченна определенным числом символов. Следовательно, такая конструкция:

    foreach i (*)
    ...
    end

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

    Например, если вы хотите найти все веб страницы на вашем сервере, которые ссылаются на URL www.example.com, вы можете использовать такую команду:

    % find / -name '*html' -print \
      | xargs grep -l 'www.example.com' \
      | less -Opages
    

    Команда xargs принимает на вход имена файлов от find и последовательно запускает grep -l для обработки каждого файла, вне зависимости от того, сколько файлов нашлось. Команда grep -l печатает имя файла, если в нем удалось в нем обнаружить указанный фрагмент текста, а затем прекращает анализ этого файла. Утилита less позволяет вам просматривать результаты по страницам и сохранить список в файл с названием pages. Результатом работы этой команды будет список файлов, которые содержат строку "www.example.com".


Заключение

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

Оставайтесь на связи!

Ресурсы

Научиться

  • Оригинал статьи (EN)
  • Работа с UNIX (EN): ознакомьтесь с другими статьями этой серии.
  • Архив переписки (EN) по zsh: ознакомьтесь с этими материалами чтобы узнать больще о приемах работы в оболочке Z.
  • AIX и UNIX: сообщество developerWorksпредлагает сотни информативных статей и обучающих курсов различной стпепени сложности по AIX и UNIX.
  • developerWorks technical events and webcasts: оставайтесь в курсе технический событий и веб-обзоров сообщества developerWorks.(EN)
  • Podcasts(EN): оставайтесь на связи с техническими экспертами IBM.

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

Обсудить

Комментарии

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=263711
ArticleTitle=Использование UNIX, Часть 1: Работа с командной строкой
publish-date=10222007