Работа с текстовыми потоками в linux. Редактирование ввода. Перенаправить ошибки в файл

Если вывод в (графическую) консоль не очень объёмный, можно просто выдельть мышкой кусок и вставить его в сообщение щелчком средней кнопки. В противном случае можно использовать перенаправление вывода в файл через "воронку", например так:

Some_command parameters > logfile.txt

Чтобы видеть результат выполнения на экране, и одновременно писать в файл, можно воспользоваться командой tee :

Some_command parameters | tee -a logfile.txt

Команда setterm -dump создает "слепок" буфера текущей виртуальной консоли в виде простого текстового файла с именем по умолчанию - screen.dump. В качестве ее аргумента можно использовать номер консоли, для которой требуется сделать дамп. А добавление опции -file имя_файла перенаправит этот дамп в файл с указанным именем. Опция же -append присоединит новый дамп к уже существующему файлу - "умолчальному" screen.dump или поименованному опцией -file .

Т.е. после использования команды, например

Setterm -dump -file /root/screenlog

соответственно в файле /root/screenlog будет содержимое одной страницы консоли.

Нашёл еще одно решение для копирования/вставки текста в текстовой консоли без мыши. Также можно копировать текст из буфера прокрутки (т.е. всё что на экране и выше за экраном). Чтобы лучше разобраться, читайте о консольном менеджере окон screen . Также может пригодиться увеличить размер буфера прокрутки.

1) Запускаем screen

2) Нажимаем Enter. Всё. Мы находимся в нулевом окне консоли.

3) Выполняем нужные команды, вывод которых необходимо скопировать.

4) Ctrl+A, Ctrl+[ - мы в режиме копирования. Ставим курсор на начало выделения, жмём пробел, потом ставим курсор на конец выделения, жмём пробел. Текст скопирован в буфер.

5) Ctrl+A, с - мы создали новое 1-е окно.

6) Ctrl+A, 1 - мы перешли на 1-е окно.

7) Открываем любой (?) текстовый редактор (я пробовал в mc), и жмём Ctrl+A, Ctrl+] - текст вставлен. Сохраняем.

8) Ctrl+A, Ctrl+0 - вернуться обратно в нулевое окно.

Как увеличить буфер обратной прокрутки?

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

И такое средство есть, а называется оно framebuffer console , для краткости fbcon . Это устройство имеет файл документации fbcon.txt ; если вы устанавливали документацию к ядру, то он у вас есть. Выискивайте его где-то в районе /usr/share ветви (я не могу указать точный путь из-за разницы в дистрибутивах).

На этом месте прошу прощения: мы должны сделать небольшое отступление и немного поговорить о видеобуфере (framebuffer ).

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

Один из таких трюков связан с буфером прокрутки; оказывается, вы можете "попросить" видеобуфер выделить больше памяти буферу прокрутки. Достигается это через загрузочные параметры ядра. Сначала вы требуете framebuffer (видеобуфер); Затем запрашиваете больший буфер прокрутки.

Нижеследующий пример касается GRUB , но может быть легко адаптирован к LILO . В файле настройки GRUB - menu.lst - найдите соответствующую ядру строчку, и затем: Удалите опцию vga=xxx , если таковая присутствует. Добавьте опцию video=vesabf или то, что соответствует вашему "железу". Добавьте опцию fbcon=scrollback:128 . После этой процедуры, строка параметров ядра должна выглядеть приблизительно так:

Kernel /vmlinuz root=/dev/sdb5 video=radeonfb fbcon=scrollback:128

Спрашивается, зачем удалять опцию vga=xxx ? Из-за возможных конфликтов с видео-опцией. На своем ATI адаптере, я не могу изменить буфер прокрутки, если vga=xxx присутствует в списке. Возможно в вашем случае это не так. Если вышеперечисленные опции работают - хорошо; но что, если вы хотите увеличить число строк, или установить более мелкий шрифт на экране? Вы всегда делали это при помощи опции vga=xxx - а она-то и исчезла. Не переживайте - то же самое может быть достигнуто изменением параметров fbcon, как описано в файле fbcon.txt (но не описано в данной статье).

С опцией fbcon=scrollback:128 у меня буфер прокрутки увеличился до 17 экранов (35 раз Shift+PgUp по полэкрана). Кстати, 128 - это килобайт. Автор статьи утверждает, что больше установить нельзя. Я и не пробовал.

Можно заюзать script .

Script filename.log

когда все нужные команды выполнены -

Все записано в filename.log

В FreeBSD есть замечательная утилита watch, которая позволяет мониторить терминалы, но как оказалось, в Linux она выполняет совсем иные функции =\ Стоит погуглить на эту тему, чего-нть да найдется...

  • Перевод

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

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

Три стандартных потока ввода/вывода

Для того, чтобы понять то, о чём мы будем тут говорить, важно знать, откуда берутся данные, которые можно перенаправлять, и куда они идут. В Linux существует три стандартных потока ввода/вывода данных.

Первый - это стандартный поток ввода (standard input). В системе это - поток №0 (так как в компьютерах счёт обычно начинается с нуля). Номера потоков ещё называют дескрипторами. Этот поток представляет собой некую информацию, передаваемую в терминал, в частности - инструкции, переданные в оболочку для выполнения. Обычно данные в этот поток попадают в ходе ввода их пользователем с клавиатуры.

Второй поток - это стандартный поток вывода (standard output), ему присвоен номер 1. Это поток данных, которые оболочка выводит после выполнения каких-то действий. Обычно эти данные попадают в то же окно терминала, где была введена команда, вызвавшая их появление.

И, наконец, третий поток - это стандартный поток ошибок (standard error), он имеет дескриптор 2. Этот поток похож на стандартный поток вывода, так как обычно то, что в него попадает, оказывается на экране терминала. Однако, он, по своей сути, отличается от стандартного вывода, как результат, этими потоками, при желании, можно управлять раздельно. Это полезно, например, в следующей ситуации. Есть команда, которая обрабатывает большой объём данных, выполняя сложную и подверженную ошибкам операцию. Нужно, чтобы полезные данные, которые генерирует эта команда, не смешивались с сообщениями об ошибках. Реализуется это благодаря раздельному перенаправлению потоков вывода и ошибок.

Как вы, вероятно, уже догадались, перенаправление ввода/вывода означает работу с вышеописанными потоками и перенаправление данных туда, куда нужно программисту. Делается это с использованием символов > и < в различных комбинациях, применение которых зависит от того, куда, в итоге, должны попасть перенаправляемые данные.

Перенаправление стандартного потока вывода

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

При использовании перенаправления любой файл, указанный после > будет перезаписан. Если в файле нет ничего ценного и его содержимое можно потерять, в нашей конструкции допустимо использовать уже существующий файл. Обычно же лучше использовать в подобном случае имя файла, которого пока не существует. Этот файл будет создан после выполнения команды. Назовём его date.txt . Расширение файла после точки обычно особой роли не играет, но расширения помогают поддерживать порядок. Итак, вот наша команда:

$ date > date.txt
Нельзя сказать, что сама по себе эта команда невероятно полезна, однако, основываясь на ней, мы уже можем сделать что-то более интересное. Скажем, вы хотите узнать, как меняются маршруты вашего трафика, идущего через интернет к некоей конечной точке, ежедневно записывая соответствующие данные. В решении этой задачи поможет команда traceroute , которая сообщает подробности о маршруте трафика между нашим компьютером и конечной точкой, задаваемой при вызове команды в виде URL. Данные включают в себя сведения обо всех маршрутизаторах, через которые проходит трафик.

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

$ traceroute google.com >> date.txt
Теперь нам осталось лишь изменить имя файла на что-нибудь более осмысленное, используя команду mv , которой, в качестве первого аргумента, передаётся исходное имя файла, а в качестве второго - новое:

$ mv date.txt trace1.txt

Перенаправление стандартного потока ввода

Используя знак < вместо > мы можем перенаправить стандартный ввод, заменив его содержимым файла.

Предположим, имеется два файла: list1.txt и list2.txt , каждый из которых содержит неотсортированный список строк. В каждом из списков имеются уникальные для него элементы, но некоторые из элементов список совпадают. Мы можем найти строки, которые имеются и в первом, и во втором списках, применив команду comm , но прежде чем её использовать, списки надо отсортировать.

Существует команда sort , которая возвращает отсортированный список в терминал, не сохраняя отсортированные данные в файл, из которого они были взяты. Можно отправить отсортированную версию каждого списка в новый файл, используя команду > , а затем воспользоваться командой comm . Однако, такой подход потребует как минимум двух команд, хотя то же самое можно сделать в одной строке, не создавая при этом ненужных файлов.

Итак, мы можем воспользоваться командой < для перенаправления отсортированной версии каждого файла команде comm . Вот что у нас получилось:

$ comm <(sort list1.txt) <(sort list2.txt)
Круглые скобки тут имеют тот же смысл, что и в математике. Оболочка сначала обрабатывает команды в скобках, а затем всё остальное. В нашем примере сначала производится сортировка строк из файлов, а потом то, что получилось, передаётся команде comm , которая затем выводит результат сравнения списков.

Перенаправление стандартного потока ошибок

И, наконец, поговорим о перенаправлении стандартного потока ошибок. Это может понадобиться, например, для создания лог-файлов с ошибками или объединения в одном файле сообщений об ошибках и возвращённых некоей командой данных.

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

Обычно, когда обычный пользователь запускает команду find по всей системе, она выводит в терминал и полезные данные и ошибки. При этом, последних обычно больше, чем первых, что усложняет нахождение в выводе команды того, что нужно. Решить эту проблему довольно просто: достаточно перенаправить стандартный поток ошибок в файл, используя команду 2> (напомним, 2 - это дескриптор стандартного потока ошибок). В результате на экран попадёт только то, что команда отправляет в стандартный вывод:

$ find / -name wireless 2> denied.txt
Как быть, если нужно сохранить результаты работы команды в отдельный файл, не смешивая эти данные со сведениями об ошибках? Так как потоки можно перенаправлять независимо друг от друга, в конец нашей конструкции можно добавить команду перенаправления стандартного потока вывода в файл:

$ find / -name wireless 2> denied.txt > found.txt
Обратите внимание на то, что первая угловая скобка идёт с номером - 2> , а вторая без него. Это так из-за того, что стандартный вывод имеет дескриптор 1, и команда > подразумевает перенаправление стандартного вывода, если номер дескриптора не указан.

И, наконец, если нужно, чтобы всё, что выведет команда, попало в один файл, можно перенаправить оба потока в одно и то же место, воспользовавшись командой &> :

$ find / -name wireless &> results.txt

Итоги

Тут мы разобрали лишь основы механизма перенаправления потоков в интерпретаторе командной строки Linux, однако даже то немногое, что вы сегодня узнали, даёт вам практически неограниченные возможности. И, кстати, как и всё остальное, что касается работы в терминале, освоение перенаправления потоков требует практики. Поэтому рекомендуем вам приступить к собственным экспериментам с > и < .

Уважаемые читатели! Знаете ли вы интересные примеры использования перенаправления потоков в Linux, которые помогут новичкам лучше освоиться с этим приёмом работы в терминале?

Примечание: практика показывает, что раздел настройки Kerberos можно пропустить. Похоже, что Samba сама настроит конфиг Kerberos. Достаточно чтобы стоял пакет krb5-user .

В ведение

Зачастую возникает необходимость ввести Linux-машину в существующий домен Windows. Например, чтобы сделать файловый сервер с помощью Samba. Сделать это очень просто, для этого вам понадобятся клиент Kerberos, Samba и Winbind.

Перед установкой желательно обновиться:

sudo aptitude update

sudo aptitude upgrade

Установить всё это добро можно командой:

sudo aptitude install krb5-user samba winbind

Также может понадобиться установить следующие библиотеки:

sudo aptitude install libpam-krb5 libpam-winbind libnss-winbind

Либо, если вы используете Ubuntu Desktop, те же пакеты можно поставить через менеджер пакетов Synaptic.

Далее вам потребуется настроить все вышеперечисленные инструменты для работы с вашим доменом. Допустим, вы хотите войти в домен DOMAIN.COM , доменконтроллером которого является сервер dc.domain.com с IP адресом 192.168.0.1 . Этот же сервер является и первичным DNS сервером домена. Кроме того допустим у вас есть второй доменконтроллер 1 ) , он же DNS - dc2.domain.com с IP 192.168.0.2 . Ваш же компьютер будет называться smbsrv01 .

Н астройка DNS

Для начала необходимо изменить настройки DNS на вашей машине, прописав в качестве DNS сервера доменконтроллер 2 ) и в качестве домена поиска - нужный домен.

Если у вас статический IP-адрес, то в Ubuntu Desktop это можно сделать через Network Manager , в Ubuntu Server необходимо изменить содержимое файла /etc/resolv.conf на примерно такое:

domain domain.com

search domain.com

nameserver 192.168.0.1

nameserver 192.168.0.2

В современных дистрибутивах файл resolv.conf создается автоматически и править вручную его не нужно. Для получение нужного результата нужно добавить необходимые изменения в файл: /etc/resolvconf/resolv.conf.d/head Данные которые будут добавлены в него, будут автоматически вставлены в файл /etc/resolv.conf

Если IP-адрес динамический и присваивается DHCP сервером то после перезагрузки resolv.conf может формироваться «неправильный» resolv.conf" , например присутствует только один nameserver 192.168.0.1 и не указаны domain и search. Нужно отредактировать /etc/dhcp/dhclient.conf . Чтобы появились записи domain и search нужно убрать комментарий перед строкой supersede domain-name, и вписать свой домен:

supersede domain-name "domain.com";

Чтобы добавить еще один nameserver нужно убрать комментарий перед prepend domain-name-servers и указать ip сервера:

prepend domain-name-servers 192.168.0.2;

Для применения изменений остается перезапустить службу:

/etc/init.d/networking restart

Теперь убедитесь, что вы задали нужное имя компьютера в файле /etc/hostname :

smbsrv01

Кроме того необходимо отредактировать файл /etc/hosts так, чтобы в нём была запись с полным доменным именем компьютера и обязательно коротким именем хоста, ссылающаяся на один из внутренних IP:

# Имена этого компьютера

127.0.0.1 localhost

127.0.1.1 smbsrv01.domain.com smbsrv01

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

ping dc

ping dc.domain.com

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

Н астройка синхронизации времени

Далее необходимо настроить синхронизацию времени с доменконтроллером. Если разница будет более 5 минут мы не сможем получить лист от Kerberos. Для единовременной синхронизации можно воспользоваться командой:

sudo net time set dc

Если в сети существует сервер точного времени, то можно воспользоваться им или любым публичным:

ntpdate ntp.mobatime.ru

Автоматическая же синхронизация настраивается с помощью ntpd , это демон будет периодически выполнять синхронизацию. Для начала его необходимо установить:

sudo aptitude install ntp

Теперь исправьте файл /etc/ntp.conf , добавив в него информацию о вашем сервере времени:

# You do need to talk to an NTP server or two (or three).

server dc.domain.com

После чего перезапустите демон ntpd :

sudo /etc/init.d/ntp restart

Теперь пора настраивать непосредственно взаимодействие с доменом.

Default_realm = DOMAIN.COM

Kdc_timesync = 1

Ccache_type = 4

Forwardable = true

Proxiable = true

V4_instance_resolve = false

V4_name_convert = {

Host = {

Rcmd = host

Ftp = ftp

Plain = {

Something = something-else

Fcc-mit-ticketflags = true

DOMAIN.COM = {

Kdc = dc

Kdc = dc2

Admin_server = dc

Default_domain = DOMAIN.COM

Domain.com = DOMAIN.COM

Domain.com = DOMAIN.COM

Krb4_convert = false

Krb4_get_tickets = false

Вам, конечно, нужно изменить domain.com на ваш домен и dc и dc2 на ваши доменконтроллеры. Кстати, возможно вам понадобится написать полные имена доменконтроллеров dc.domain.com и dc2.domain.com . Поскольку у меня прописан домен поиска в DNS, то мне это делать не нужно.

Обратите особое внимание на регистр написания имени домена - везде, где домен написан в верхнем регистре, его обязательно нужно писать именно в верхнем регистре. Иначе волшебным образом ничего может не заработать.

Это не все возможные опции настройки Kerberos, только основные. Однако их обычно достаточно.

Теперь настало время проверить, что мы можем авторизоваться в домене. Для этого выполните команду

kinit [email protected]

Вместо username естественно стоит вписать имя существующего пользователя домена.

Имя домена необходимо писать заглавными буквами!

Если вы не получили никаких ошибок - значит вы настроили всё верно и домен отдаёт вам билет Kerberos. Кстати, некоторые распространённые ошибки перечислены чуть ниже.

Убедиться в том, что билет получен, можно выполнив команду

klist

Удалить все билеты (они вам вообще говоря не нужны) можно командой

kdestroy

Р аспространённые ошибки kinit

kinit(v5): Clock skew too great while getting initial credentials

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

kinit(v5): Preauthentication failed while getting initial credentials

Вы ввели неверный пароль.

kinit(v5): KDC reply did not match expectations while getting initial credentials

Самая странная ошибка. Убедитесь, что имя realm в krb5.conf , а так же домен в команде kinit введены большими буквами:

DOMAIN.COM = {

# ...

kinit [email protected]

kinit(v5): Client not found in Kerberos database while getting initial credentials

Указанного пользователя не существует в домене.

Н астройка Samba и вход в домен

Для того, чтобы войти в домен, необходимо прописать правильные настройки в файле /etc/samba/smb.conf . На данном этапе вас должны интересовать только некоторые опции из секции . Ниже - пример части файла конфигурации Samba с комментариями по поводу значения важных параметров:

# Эти две опции нужно писать именно в заглавном регистре, причём workgroup без

# последней секции после точки, а realm - полное имя домена

Workgroup = DOMAIN

Realm = DOMAIN.COM

# Эти две опции отвечают как раз за авторизацию через AD

Security = ADS

Encrypt passwords = true

# Просто важные

Dns proxy = no

Socket options = TCP_NODELAY

# Если вы не хотите, чтобы самба пыталась при случае вылезти в лидеры в домене или рабочей группе,

# или даже стать доменконтроллером, то всегда прописывайте эти пять опций именно в таком виде

Domain master = no

Local master = no

Preferred master = no

Os level = 0

Domain logons = no

# Отключить поддержку принтеров

Load printers = no

Show add printer wizard = no

Printcap name = /dev/null

Disable spoolss = yes

После того, как вы отредактируете smb.conf выполните команду

testparm

Она проверит вашу конфигурацию на ошибки и выдаст суммарную сводку о нём:

# testparm

Load smb config files from /etc/samba/smb.conf

Loaded services file OK.

Server role: ROLE_DOMAIN_MEMBER

Press enter to see a dump of your service definitions

Как видно мы задали правильные параметры для того, чтобы наш компьютер стал членом домена. Теперь пора попытаться непосредственно войти в домен. Для этого введите команду:

net ads join -U username -D DOMAIN

И в случае успеха вы увидите что-то похожее на:

# net ads join -U username -D DOMAIN

Enter username"s password:

Using short domain name -- DOMAIN

Joined "SMBSRV01" to realm "domain.com"

И спользуемые параметры команды net

U username%password : Обязательный параметр, вместо username необходимо подставить имя пользователя с правами администратора домена, и указать пароль.

D DOMAIN : DOMAIN - собственно сам домен, домен можно и не указывать, но лучше всё же это всегда делать - хуже не будет.

S win_domain_controller : win_domain_controller , можно не указывать, но бывают случаи когда автоматически сервер не находит контроллер домена.

createcomputer=«OU/OU/…» : В AD часто используется OU (Organizational Unit), есть в корне домена OU = Office, в нем OU = Cabinet, чтобы сразу добавить в нужный можно указать так: sudo net ads join -U username createcomputer=«Office/Cabinet».

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

Так же можно набрать команду:

net ads testjoin

Если все хорошо, можно увидеть:

#net ads testjoin

Join is OK

Но иногда после сообщения о присоединении к домену выдаётся ошибка наподобие 3 ) :

DNS update failed!

Это не очень хорошо, и в этом случае рекомендуется ещё раз прочитать раздел про настройку DNS чуть выше и понять, что же вы сделали не так. После этого нужно удалить компьютер из домена и попытаться ввести его заново. Если вы твердо уверены, что всё настроили верно, а DNS всё равно не обновляется, то можно внести вручную запись для вашего компьютера на ваш DNS сервер и всё будет работать. Конечно, если нет никаких других ошибок, и вы успешно вошли в домен. Однако лучше всё же разберитесь, почему DNS не обновляется автоматически. Это может быть связано не только с вашим компьютером, но и с некорректной настройкой AD.

Прежде чем выяснять, почему же не обновляется DNS, не забудьте перезагрузить компьютер после введения в домен! Вполне возможно, что это решит проблему.

Если всё прошло без ошибок, то поздравляем, вы успешно вошли в домен! Можете заглянуть в AD и убедиться в этом. Кроме того хорошо бы проверить, что вы можете видеть ресурсы в домене. Для этого установите smbclient :

sudo aptitude install smbclient

Теперь можно просматривать ресурсы компьютеров домена. Но для этого нужно иметь билет kerberos, т.е. если мы их удалили, то получаем опять через kinit (см. выше). Посмотрим какие ресурсы предоставлены в сеть компьютером workstation :

smbclient -k -L workstation

Вы должны увидеть список общих ресурсов на этом компьютере.

Н астройка Winbind

Если вам необходимо как-либо работать с пользователями домена, например, настраивать SMB-шары с разграничением доступа, то вам понадобится кроме самой Samba ещё и Winbind - специальный демон, служащий для связи локальной системы управления пользователями и группами Linux с сервером Active Directory. Проще говоря Winbind нужен, если вы хотите видеть пользователей домена на своём компьютере с Ubuntu.

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

Для настройки Winbind используется всё тот же файл /etc/samba/smb.conf . Добавьте в секцию следующие строки:

# Опции сопоставления доменных пользователей и виртуальных пользователей в системе через Winbind.

# Диапазоны идентификаторов для виртуальных пользователей и групп.

Idmap uid = 10000 - 40000

Idmap gid = 10000 - 40000

# Эти опции не стоит выключать.

Winbind enum groups = yes

Winbind enum users = yes

# Использовать домен по умолчанию для имён пользователей. Без этой опции имена пользователей и групп

# будут использоваться с доменом, т.е. вместо username - DOMAIN\username.

# Возможно именно это вам и нужно, однако обычно проще этот параметр включить.

Winbind use default domain = yes

# Если вы хотите разрещить использовать командную строку для пользователей домена, то

# добавьте следующую строку, иначе в качестве shell"а будет вызываться /bin/false

Template shell = /bin/bash

# Для автоматического обновления билета Kerberos модулем pam_winbind.so нужно добавить строчку

Winbind refresh tickets = yes

Параметры:

idmap uid = 10000 - 40000

idmap gid = 10000 - 40000

в новых версиях Samba уже устарели и при проверке конфига самбы с помощью testparm будет выдваться предупреждение:

WARNING: The «idmap uid» option is deprecated

WARNING: The «idmap gid» option is deprecated

Чтобы убрать предупреждения нужно заменить эти строки на новые:

idmap config * : range = 10000-20000

idmap config * : backend = tdb

Теперь перезапустите демон Winbind и Samba в следующем порядке:

sudo /etc/init.d/winbind stop

sudo smbd restart

sudo /etc/init.d/winbind start

Запускаем

sudo testparm

Смотрим есть ли ошибки или предупреждения, если появится:

«rlimit_max: rlimit_max (1024) below minimum Windows limit (16384)»

Без перезагрузки можно устранить так:

ulimit -n 16384

Для сохранения после перезагрузки отредактировать файл /etc/security/limits.conf

# Добавить в конец файла строки:

* - nofile 16384

root - nofile 16384

После перезапуска проверьте, что Winbind установил доверительные отношения с AD командой:

# wbinfo -t

checking the trust secret for domain DCN via RPC calls succeeded

А так же, что Winbind увидел пользователей и группы из AD командами 4 ) :

wbinfo -u

wbinfo -g

Эти две команды должны выдать список пользователей и групп из домена соответственно. Либо с префиксом DOMAIN\ , либо без него - в зависимости от того, какое значение вы указали параметру «winbind use default domain» в smb.conf .

Итак, Winbind работает, однако в систему он ещё не интегрирован.

Д обавление Winbind в качестве источника пользователей и групп

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

Для этого измените две строчки в файле /etc/nsswitch.conf :

passwd: compat

group: compat

добавив к ним в конец winbind :

passwd: compat winbind

group: compat winbind

files: dns mdns4_minimal mdns4

ubuntu server 14.04, файл /etc/nsswitch.conf не содержал строку «files: dns mdns4_minimal mdns4» вместо неё было: «hosts: files mdns4_minimal dns wins» Которую я преобразовал в: «hosts: dns mdns4_minimal mdns4 files» после чего всё заработало

Теперь проверьте, что Ubuntu запрашивает у Winbind информацию о пользователях и группах, выполнив

getent passwd

getent group

Первая команда должна вам вернуть всё содержимое вашего файла /etc/passwd , то есть ваших локальных пользователей, плюс пользователей домена с ID из заданного вами в smb.conf диапазона. Вторая должна сделать тоже самое для групп.

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

А вторизация в Ubuntu через пользователей домена

Несмотря на то, что все пользователи домена фактически стали полноценными пользователями системы (в чём можно убедиться, выполнив последние две команды из предыдущего раздела), зайти ни под кем из них в систему всё ещё нельзя. Для включения возможности авторизации пользователей домена на компьютере с Ubuntu необходимо настроить PAM на работу с Winbind.

Для Ubuntu 10.04 и выше добавьте всего одну строку в файле /etc/pam.d/common-session , т.к. PAM и так неплохо справляется с авторизацией:

Для Ubuntu 13.10 чтобы появилось поле ручного ввода логина необходимо в любой файл из папки /etc/lightdm/lightdm.conf/ снизу добавить строку:

greeter-show-manual-login=true

Для Ubuntu 9.10 и ниже придется редактировать несколько файлов (но никто не запрещает использовать этот способ и в 10.04 - он тоже работает):

Последовательность строк в файлах имеет значение!

/etc/pam.d/common-auth

auth required pam_env.so

auth sufficient pam_unix.so likeauth nullok try_first_pass

auth sufficient pam_winbind.so use_first_pass krb5_auth krb5_ccache_type=FILE

auth required pam_deny.so

/etc/pam.d/common-account

account sufficient pam_winbind.so

account required pam_unix.so

/etc/pam.d/common-session

session optional pam_mkhomedir.so skel=/etc/skel/ umask=0077

session optional pam_ck_connector.so nox11

session required pam_limits.so

session required pam_env.so

session required pam_unix.so

/etc/pam.d/common-password

password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow

password sufficient pam_winbind.so

password required pam_deny.so

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

sudo bash -c "for i in 2 3 4 5; do mv /etc/rc$i.d/S20winbind /etc/rc$i.d/S99winbind; done"

Что эквивалентно запуску для каждого уровня (в примере - 4) команды:

mv /etc/rc4.d/S20winbind /etc/rc4.d/S99winbind

В некоторых случаях winbind может иметь иной уровень запуска (например, S02winbind). Поэтому сначала проверьте имена файлов, вполнив команду «ls /etc/rc{2,3,4,5}.d/ | grep winbind» (без кавычек).

Готово, все настройки завершены. Перезагружайтесь и пытайтесь войти с учетной записью пользователя домена.

Часто возникает ситуация, когда домен-контроллер недоступен по различным причинам - профилактика, отключение света или вы принесли ноутбук домой и хотите поработать. В этом случае для Winbind можно настроить кэширование учетных записей пользователей домена. Для этого необходимо сделать следующее. Добавьте в секцию файла /etc/samba/smb.conf следующие строки:

Winbind offline logon = yes

# Период кэширования учетных записей, по умолчанию равен 300 секунд

Winbind cache time = 300

# Необязательная настройка, но избавляет от нудных пауз, указываем контроллер домена dc,

# можно указать и ip, но это является плохим тоном

Password server = dc

Обычно этого достаточно. Если же возникают ошибки, то необходимо создать файл /etc/security/pam_winbind.conf со следующим содержанием 5 ) :

Внимание! При использовании советов ниже может возникать совершенно случайная ошибка «Сбой аутентификации»! Поэтому все что Вы делаете, Вы делаете на свой страх и риск!

# pam_winbind configuration file

# /etc/security/pam_winbind.conf

# turn on debugging

Debug = no

# request a cached login if possible

# (needs "winbind offline logon = yes" in smb.conf)

Cached_login = yes

# authenticate using kerberos

Krb5_auth = yes

# when using kerberos, request a "FILE" krb5 credential cache type

# (leave empty to just do krb5 authentication but not have a ticket

# afterwards)

Krb5_ccache_type = FILE

# make successful authentication dependend on membership of one SID

# (can also take a name)

;require_membership_of =

Silent = yes

Файл /etc/pam.d/gnome-screensaver в таком случае принимает вид:

auth sufficient pam_unix.so nullok_secure

auth required pam_deny.so

А также изменяется файл /etc/pam.d/common-auth :

auth optional pam_group.so

auth sufficient pam_unix.so nullok_secure use_first_pass

auth sufficient pam_winbind.so use_first_pass

auth required pam_deny.so

Любая программа - это "автомат", предназначенный для обработки данных: получая на входе одну информацию, она в результате работы выдает другую. Хотя входящая и/или выходящая информация может быть и нулевой, т. е. попросту отсутствовать. Те данные, которые передаются программе для обработки - это ее ввод, то, что она выдает в результате работы - вывод. Организация ввода и вывода для каждой программы - это задача операционной системы.

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

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

Рассмотрим сначала пару команд, с помощью которых можно организовать ввод/вывод.

Команды вывода на стандартное устройство вывода

Linux предоставляет несколько команд для вывода сообщений в стандартный поток вывода:

  • echo - Вывести строку в стандартный поток вывода.
  • printf - Вывести форматированный текст в стандартный поток вывода.
  • yes - Выводить повторяющийся текст в стандартный поток вывода.
  • seq - Вывести последовательность чисел в стандартный поток вывода
  • clear Очистить экран или окно.

Например, при использовании команды echo если указать управляющий символ \с, то по завершении вывода не будет осуществлен переход в новую строку:

$ echo "Как вас зовут?\c"

Как вас зовут?$

Здесь $ – символ приглашения.

В строке также можно вычислять значения переменных интерпретатора shell и даже других команд. Например, следующая команда сообщает о том, каков начальный каталог текущего пользователя (переменная среды $HOME) и к какому терминалу он подключен (команда tty заключена в обратные кавычки, чтобы интерпретатор поместил в строку результат ее выполнения).

$ echo "Ваш начальный каталог - $HOME, вы подключены к терминалу - `tty` "

Ваш начальный каталог - /home/knoppix, вы подключены к терминалу - /dev/tty1

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

Например, чтобы вывести строку “/dev/tty1” необходимо выполнить:

$echo “\”/dev/tty1\””

Команды ввода из стандартного устройства ввода

Команда read читает одну строку из стандартного входного потока и записывает ее содержимое в указанные переменные. При указании нескольких переменных в первую из них записывается первое слово, во вторую – второе и т.д. в последнюю – остаток строки.

Следующий сценарий вызывает отдельную команду read для чтения каждой переменной.


$ cat test
#!/bin/bash
echo “Имя: \с”
read name
echo “Фамилия: \c”
read surname
echo “Имя=” $name “Фамилия=” $surname

Тогда для выполнения этого сценария необходимо файлу test дать право выполнения: chmod 0755 test и запустить его./test. Результат выполнения: Имя: Иван Фамилия: Петров Имя=Иван Фамилия=Петров

СТАНДАРТНЫЕ ПОТОКИ ВВОДА, ВЫВОДА И ОШИБОК

Каждая запущенная из командного интерпретатора программа получает три открытых потока ввода/вывода:

Стандартный ввод (sldin) - стандартный вывод(sldout) - стандартный вывод ошибок (stderr)

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

При этом с каждым процессом (командой, сценарием и т.п.), выполняемым в интерпретаторе shell, связан рад открытых файлов, из которых процесс может читать свои данные: и в которые он может записывать их. Каждый из этих файлов идентифицируется числом, называемым дескриптором файла, но первые три файла являются потоками ввода/вывода по умолчанию:

Файл Дескриптор
Стандартный поток ввода 0
Стандартный поток вывода 1
Стандартный поток ошибок 2

В действительности создается 12 открытых файлов, но файлы с дескрипторами 0, 1 и 2 резервируются для стандартных потоков ввода, вывода и ошибок. Пользователи могут также работать с файлами, имеющими дескрипторы от 3 до 9 (зарезервированы).

Файл стандартного потока ввода (sldin) имеет дескриптор 0. Из этого файла процессы извлекают свои входные данные. По умолчанию входной поток ассоциирован с клавиатурой (устройство /dev/tty), но чаше всего он поступает по каналу от других процессов или из обычного файла.

Файл стандартного потока вывода (stdout) имеет дескриптор 1. В этот файл записываются все выходные данные процесса. По умолчанию данные выводятся на экран терминала (устройство/dev/tty), но их можно также перенаправить в файл или послать по каналу другому процессу.

Файл стандартного потока ошибок (siderr) имеет дескриптор 2. В этот файл записываются сообщения об ошибках, возникающих в ходе выполнения команды. По умолчанию сообщения об ошибках выводятся на экран терминала (устройство /dev/tty), но их также можно перенаправить в файл. Зачем же для регистрации ошибок выделять специальный файл? Дело в том, что это очень удобный способ выделения из результатов работы команды собственно выходных данных, а также хорошая возможность эффективно организовать ведение различного рода журнальных файлов.

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

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

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

% cat myfile - создаст в текущей директории пустой файл myfile.

/dev/null - специальный файл, представляющий собой т. н. «пустое устройство». Запись в него происходит успешно, независимо от объёма «записанной» информации. Чтение из /dev/null эквивалентно считыванию конца файла EOF.

Перенаправление потоков ввода-вывода осуществляется, подобно DOS (Точнее, синтаксис перенаправления потоков ОС DOS восприняла от UNIX) с помощью символов:

> - перенаправление стандартного потока вывода
>> - перенаправление стандартного потока вывода в режиме дозаписи
< - перенаправление стандартного потока ввода
<< - получение данные из стандартного потока ввода до тех пор, пока не встретится разделитель

Однако, в отличие от DOS при создании программного канала между двумя процессами ОС UNIX/Linux запускает оба процесса одновременно и осуществляет передачу информации через системный буфер (без промежуточной записи на жесткий диск). Таким образом, программные каналы в ОС UNIX/Linux являются весьма эффективным способом обмена. В случае переполнения системного буфера (например если ``передающая"" программа выдает информацию в канал быстрее чем ее может обработать ``принимающая"" программа) ОС автоматически приостанавливает тот процесс, который осуществляет запись в канал до освобождения буфера.

Наиболее распространенные операторы переадресации

№п/п Синтаксис Описание
1 команда > файл Направляет стандартный поток вывода в новый файл

2 команда 1> файл Направляет стандартный поток вывода в указанный файл

3 команда >> файл Направляет стандартный поток вывода в указанный файл (режим присоединения)

4 команда > файл 2>&1 Направляет стандартные потоки вывода и ошибок в указанный файл

5 команда 2> файл Направляет стандартный поток ошибок в указанный файл

6 команда 2>> файл Направляет стандартный поток ошибок в указанный файл (режим присоединения)

7 команда >> файл 2>&1 Направляет стандартные потоки вывода и ошибок в указанный файл (режим присоединения)

8 команда < файл1 > файл2 Получает входные данные из первого файла и направляет выходные данные во второй файл

9 команда < файл в качестве стандартного входного потока получает данные из указанного файла

10 команда << разделитель Получает данные из стандартного потока ввода до тех пор, пока не встретится разделитель

11 команда <&m В качестве стандартного входного потока получает дан­ные из файла с дескриптором m

12 команда >&m Направляет стандартный поток вывода в файл с дескриптором m

Оператор n>&m позволяет перенаправить файл с дескриптором n туда, куда направлен файл с дескриптором m. Подобных операторов в командной строке может быть несколько, в этом случае они вычисляются слева направо.

Команда exec и применение дескрипторов файлов

Команда exec заменяет текущий интерпретатор shell указанной командой. Обычно она используется для того, чтобы закрыть текущий интерпретатор и запустить другой. Но у нее есть и другое применение.

Например, команда вида

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

Exec <&– которая закрывает стандартный входной поток (в данном случае файл). Подобный прием применяется
преимущественно в сценариях, выполняющихся при выходе из системы.

Команда exec указатель на файл с дескриптором 0 (stdin). Восстановить этот указатель можно будет только по завершении работы сценария.
Если же в сценарии предполагается продолжить чтение данных с клавиатуры, то необходимо сохранить
указатель на прежний входной поток. Ниже приведен небольшой сценарий, в котором демонстрируется, как это сделать.

$ cat f_desc
#!/bin/bash
exec 3<&0 0<file
read linel
read line2
exec 0<&3
echo $1inel
echo $line2

Первая команда exec сохраняет указатель на стандартный входной поток (stdin) в файле с дескриптором 3
(допускается любое целое число в диапазоне от 3 до 9), а затем открывает файл file для чтения. Следующие две команды read
читают из файла две строки текста. Вторая команда exec восстанавливает указатель на стандартный входной поток: теперь
он связан с файлом stdin, а не file. Завершающие команды echo отображают на экране содержимое прочитанных строк,
которые были сохранены в переменных linel и Iine2.

Результат работы сценария:
$ ./ f_desc
Привет!
Пока!

Изучаем Linux, 101

Текстовые потоки и фильтры

Обработка текста в командной строке с использованием текстовых утилит GNU

Серия контента:

Краткий обзор

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

В этой статье будут рассмотрены следующие темы:

Об этой серии

Эта серия статей поможет вам освоить задачи администрирования операционной системы Linux. Вы также можете использовать материал этих статей для подготовки к .

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

  • Обработка текстовых файлов и потоков вывода текстовыми фильтрами для модификации вывода.
  • Использование стандартных команд UNIX из состава пакета GNU textutils.
  • Использование редактора sed для создания сценариев, состоящих из сложных последовательностей действий над текстовыми файлами.

Эта статья поможет вам подготовиться к сдаче экзамена LPI 101 на администратора начального уровня (LPIC-1) и содержит материалы цели 103.2 темы 103. Цель имеет вес 3. Материал этой статьи соответствует целям экзамена LPI 101 по состоянию на апрель 2009 года. Всегда обращайтесь к Web-сайту программы сертификации LPIC, чтобы уточнить последние цели.

Необходимые условия

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

Фильтрация текста

Как связаться с Яном

Ян – один из наших наиболее популярных и плодовитых авторов. Ознакомьтесь со (EN), опубликованными на сайте developerWorks. Вы можете найти контактные данные в и связаться с ним, а также с другими авторами и участниками ресурса My developerWorks.

Фильтрация текста – это процесс получения входного текстового потока, выполнения неких преобразований над ним и передача измененных данных в выходной поток. Хотя входные или выходные данные могут поступать из файлов, в UNIX® и Linux фильтрация обычно осуществляется путем составления конвейеров из команд, в которых вывод одной команды передается по программному каналу (или перенаправляется ) на вход следующей команде. Более подробно программные каналы и перенаправления рассматриваются в статье "Потоки, программные каналы и перенаправления " (см. ), а сейчас давайте рассмотрим программные каналы и простые перенаправления вывода с помощью операторов | и >.

Потоки

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

  • stdin стандартный поток ввода (standard input stream), обеспечивающий ввод для команд.
  • stdout стандартный поток вывода (standard output stream), обеспечивающий отображение результатов выполнения команд.
  • stderr стандартный поток ошибок (standard error stream), обеспечивающий отображение ошибок, возникающих при выполнении команд.

Конвейеризация с использованием оператора |

Передаваемые командам параметры могут служить входными данными этих команд, а выходные данные могут выводиться на ваш терминал. Многие команды обработки текста (фильтры) могут получать входные данные либо из стандартного потока ввода, либо из файла. Чтобы передать вывод команды1 на вход команде2 (выступающей в качестве фильтра), необходимо соединить эти две команды оператором конвейеризации ввода/вывода (|). В листинге 1 показано, как перенаправить вывод команды echo на вход команде sort , которая сортирует полученный список слов.

Листинг 1. Передача вывода команды echo на вход команды sort
$ echo -e "apple\npear\nbanana"|sort apple banana pear

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

Перенаправление вывода с помощью оператора >

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

В оставшихся примерах этой статьи мы будем использовать небольшие файлы, поэтому давайте создадим директорию с именем lpi103-2 и перейдем в нее. После этого давайте перенаправим с помощью оператора > вывод команды echo в файл с именем text1. Эти действия показаны в листинге 2. Заметьте, что поскольку весь вывод перенаправляется в файл, он не отображается на экране.

Листинг 2. Перенаправление вывода команды в файл
$ mkdir lpi103-2 $ cd lpi103-2 $ echo -e "1 apple\n2 pear\n3 banana" > text1

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

Команды cat, od и split

После того, как вы создали файл test1, вы можете просмотреть его содержимое. Для вывода содержимого файла на стандартное устройство вывода используется команда cat (сокращенно от concatenate – объединять). В листинге 3 на экран выводится содержимое только что созданного нами файла.

Листинг 3. Вывод содержимого файла с помощью команды cat
$ cat text1 1 apple 2 pear 3 banana

Если не указать имя файла (или поставить вместо имени файла дефис), то команда cat принимает входные данные со стандартного устройства ввода. Давайте используем эту возможность (а также перенаправление вывода) для создания еще одного текстового файла, как показано в листинге 4.

Листинг 4. Создание текстового файла с помощью команды cat
$ cat >text2 9 plum 3 banana 10 apple
Другие простые фильтры

Другим примером простого фильтра является команда tac (перевернутое имя команды cat). Эта команда выполняет действие команды cat наоборот – строки файла выводятся в обратном порядке. Попробуйте самостоятельно выполнить следующую команду:
tac text2 text1

В листинге 4 команда cat продолжает считывать данные с устройства stdin до тех пор, пока не будет достигнут конец файла. Чтобы обозначить конец файла, нажмите комбинацию клавиш Ctrl-d (удерживайте Ctrl и нажмите d ). Эта же комбинация клавиш используется для выхода из командного интерпретатора bash. Используйте клавишу табуляции, чтобы выстроить названия фруктов в столбец.

Вы еще не забыли, что cat – это сокращение от concatenate ? С помощью cat вы можете объединить несколько файлов и вывести их содержимое на экран. В листинге 5 показано содержимое двух файлов, которые мы создали.

Листинг 5. Объединение двух файлов с помощью команды cat
$ cat text* 1 apple 2 pear 3 banana 9 plum 3 banana 10 apple

Обратите внимание на различное выравнивание содержимого двух текстовых файлов при выводе их на экран с помощью cat . Чтобы разобраться, почему это происходит, необходимо посмотреть на управляющие символы, которые присутствуют в файлах. Эти символы влияют на вывод текста, но не имеют визуального отображения, поэтому необходимо создать дамп файла в формате, позволяющем увидеть и определить эти специальные символы. Для этих целей предназначена GNU-утилита od (O ctal D ump).

Команда od имеет несколько опций; например, опция -A управляет основанием смещения файлов, а опция -t – формой выводимого содержимого. Основание может быть указано как o (восьмеричное, используется по умолчанию), d (десятичное), x (шестнадцатеричное) или n (смещения не отображаются). Вы можете выводить содержимое в виде восьмеричных, шестнадцатеричных, десятичных значений, значений с плавающей точкой, ASCII-символов с escape-последовательностями или именованных символов (nl – для новой строки, ht – для горизонтальной табуляции и т. д.). В листинге 6 показано несколько доступных форматов дампа файла text2 из нашего примера.

Листинг 6. Дампы файлов, созданные с помощью команды od
$ od text2 0000000 004471 066160 066565 031412 061011 067141 067141 005141 0000020 030061 060411 070160 062554 000012 0000031 $ od -A d -t c text2 0000000 9 \t p l u m \n 3 \t b a n a n a \n 0000016 1 0 \t a p p l e \n 0000025 $ od -A n -t a text2 9 ht p l u m nl 3 ht b a n a n a nl 1 0 ht a p p l e nl

Примечания:

Файлы, используемые в наших примерах, очень малы, но иногда вам могут встретиться большие файлы, которые необходимо разделить на несколько более мелких. Например, вам может потребоваться разбить один большой файл на несколько частей такого размера, чтобы их можно было записать на компакт-диски. Для этого можно использовать команду split , которая разбивает файлы таким образом, что впоследствии их можно легко собрать обратно в единый файл при помощи команды cat . По умолчанию имена файлов, создаваемых командой split , состоят из префикса "x", за которым следует суффикс "aa", "ab", "ac", ..., "ba", "bb" и так далее. Эти умолчания можно изменить с помощью различных опций. Вы также можете задавать размер выходных файлов и определять, будут ли они содержать определенное количество строк или просто иметь определенный размер в байтах.

В листинге 7 показано разделение наших двух текстовых файлов с использованием различных префиксов для выходных файлов. Файл text1 мы разделили на файлы, содержащие максимум две строки, а файл text2 – на файлы максимальным размером в 18 байтов. Далее с помощью команды cat мы отобразили некоторые отдельные части, а также весь файл целиком, используя универсализацию файловых имен , которая рассматривается в статье "Основы управления файлами и директориями " (см. ).

Листинг 7. Разделение и восстановление файлов с помощью команд split и cat
$ split -l 2 text1 $ split -b 17 text2 y $ cat yaa 9 plum 3 banana 1$ cat yab 0 apple $ cat y* x* 9 plum 3 banana 10 apple 1 apple 2 pear 3 banana

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

Команды wc, head и tail

Команда cat выводит полное содержимое файла. Это хорошо подходит для небольших файлов (например, для наших примеров), но что делать, если объем файла очень большой? Итак, для начала можно оценить размер файла с помощью команды wc (W ord C ount – подсчет слов). Команда wc выводит количество содержащихся в файле строк и слов, а также размер файла в байтах, определить который можно также с помощью команды ls -l . В листинге 8 показан подробный вывод сведений о наших двух текстовых файлах, а также вывод команды wc .

Листинг 8. Использование команды wc для работы с текстовыми файлами
$ ls -l text* -rw-rw-r--. 1 ian ian 24 2009-08-11 14:02 text1 -rw-rw-r--. 1 ian ian 25 2009-08-11 14:27 text2 $ wc text* 3 6 24 text1 3 6 25 text2 6 12 49 total

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

Две другие команды позволяют отображать либо первую часть файла (заголовок ), либо последнюю (хвост ). Эти команды так и называются – head и tail соответственно. Их можно использовать в качестве фильтров или передавать им в качестве аргумента имя файла. По умолчанию эти команды отображают 10 первых (или последних) строк файла или потока. В листинге 9 совместно используются команды dmesg (отображение информации о загрузке системы), wc , tail и head ; в результате мы видим, что файл содержит 791 сообщение, выводим последние 10 из них, а затем выводим шесть сообщений, начиная с 15 от конца.

Листинг 9. Использование команд wc, head и tail для вывода сообщений о загрузке
$ dmesg|wc 791 5554 40186 $ dmesg | tail input: HID 04b3:310b as /devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2.4/3-2.4:1.0/input/i nput12 generic-usb 0003:04B3:310B.0009: input,hidraw1: USB HID v1.00 Mouse on us b-0000:00:1a.0-2.4/input0 usb 3-2.4: USB disconnect, address 11 usb 3-2.4: new low speed USB device using uhci_hcd and address 12 usb 3-2.4: New USB device found, idVendor=04b3, idProduct=310b usb 3-2.4: New USB device strings: Mfr=0, Product=0, SerialNumber=0 usb 3-2.4: configuration #1 chosen from 1 choice input: HID 04b3:310b as /devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2.4/3-2.4:1.0/input/i nput13 generic-usb 0003:04B3:310B.000A: input,hidraw1: USB HID v1.00 Mouse on us b-0000:00:1a.0-2.4/input0 usb 3-2.4: USB disconnect, address 12 $ dmesg | tail -n15 | head -n 6 usb 3-2.4: USB disconnect, address 10 usb 3-2.4: new low speed USB device using uhci_hcd and address 11 usb 3-2.4: New USB device found, idVendor=04b3, idProduct=310b usb 3-2.4: New USB device strings: Mfr=0, Product=0, SerialNumber=0 usb 3-2.4: configuration #1 chosen from 1 choice input: HID 04b3:310b as /devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2.4/3-2.4:1.0/input/i nput12

Другим распространенным применением команды tail является слежение за файлом; для этого используется опция -f и шаг, обычно равный одной строке. Это может оказаться полезным в том случае, если у вас имеется фоновый процесс, генерирующий вывод данных в файл, и вы хотите следить за ходом его выполнения. В этом режиме команда tail будет работать и выводить строки по мере их добавления в файл до тех пор, пока вы не завершите ее работу, нажав Ctrl-c .

Команды expand, unexpand и tr

Когда мы создавали наши файлы text1 и text2, в последнем из них были использованы символы табуляции. Иногда вам может потребоваться заменить символы табуляции на символы пробела и наоборот. Для этого предназначены команды expand и unexpand . В обеих командах опция -t позволяет устанавливать позиции табуляции. Если после этой опции указывается только одно значение, то позиции табуляции будут периодически расставляться через этот указанный интервал. В листинге 10 показано, как сократить символы табуляции в файле text2 до одиночных пробелов, а также приведена причудливая последовательность из команд expand и unexpand и нарушающая выравнивание текста в файле text2.

Листинг 10. Использование команд expand и unexpand
$ expand -t 1 text2 9 plum 3 banana 10 apple $ expand -t8 text2|unexpand -a -t2|expand -t3 9 plum 3 banana 10 apple

К сожалению, вы не можете использовать команду unexpand для замены пробелов в файле text1 на символы табуляции, поскольку для преобразования в символ табуляции команде unexpand требуется, как минимум, два последовательных пробела. Однако вы можете использовать команду tr , которая преобразует символы из одного набора (набор1 ) в соответствующие символы из другого набора (набор2 ). В листинге 11 показан пример использования команды tr для преобразования пробелов в символы табуляции. Поскольку команда tr представляет собой фильтр в чистом виде, то входные данные для нее генерируются с помощью команды cat . В этом примере также показан пример использования дефиса (-) с целью указать cat на то, что ввод будет осуществляться со стандартного устройства; таким образом, мы можем объединить вывод команды tr с содержимым файла text2.

Листинг 11. Использование команды tr
$ cat text1 |tr " " "\t"|cat - text2 1 apple 2 pear 3 banana 9 plum 3 banana 10 apple

Если вы не очень понимаете, что происходит в последних двух примерах, то попробуйте использовать команду od , чтобы последовательно выполнить каждую команду конвейера, например:
cat text1 |tr " " "\t" | od -tc

Команды Pr, nl и fmt

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

Команда nl нумерует строки, что может оказаться полезным при печати файлов. Для нумерации строк можно также использовать команду cat с опцией -n . В листинге 12 показано, как распечатать наш текстовый файл, пронумеровать строки в файле text2 и вывести его на печать вместе с файлом text1.

Листинг 12. Нумерация строк и форматирование перед печатью
$ pr text1 | head 2009-08-11 14:02 text1 Page 1 1 apple 2 pear 3 banana $ nl text2 | pr -m - text1 | head 2009-08-11 15:36 Page 1 1 9 plum 1 apple 2 3 banana 2 pear 3 10 apple 3 banana

Другой полезной командой для форматирования текста является команда fmt , которая форматирует текст таким образом, чтобы он не выходил за границы полей. Можно объединить несколько коротких строк в одну длинную и наоборот. В листинге 13 мы создали файл text3, используя одну длинную конструкцию из комбинаций символов!#:* (предназначенных для управления историей команд), благодаря чему, напечатанное предложение было сохранено в файле четыре раза. Также мы создали файл text4, содержащий по одному слову в каждой строке. Затем с помощью команды cat мы отобразили содержимое этих файлов в неформатированном виде, включая символ конца строки "$". Наконец, с помощью команды fmt мы отформатировали эти файлы, ограничив максимальное значение длины строки 60 символами. Как обычно, дополнительную информацию вы можете найти на man-странице.

Листинг 13. Форматирование с указанием максимальной длины строки
$ echo "This is a sentence. " !#:* !#:1->text3 echo "This is a sentence. " "This is a sentence. " "This is a sentence. ">text3 $ echo -e "This\nis\nanother\nsentence.">text4 $ cat -et text3 text4 This is a sentence. This is a sentence. This is a sentence. $ This$ is$ another$ sentence.$ $ fmt -w 60 text3 text4 This is a sentence. This is a sentence. This is a sentence. This is another sentence.

Команды sort и uniq

Команда sort сортирует входные данные с использованием схемы упорядочивания локали (LC_COLLATE) системы. Команда sort также может объединять уже отсортированные файлы и определять, является ли файл отсортированным или нет.

В листинге 14 приведены примеры использования команды sort для сортировки двух текстовых файлов после замены в файле text1 пробелов на символы табуляции. Поскольку сортировка выполняется на основе символьных значений, вы можете удивиться, увидев результаты. К счастью, команда sort может выполнять сортировку не только на основе символьных, но также и на основе числовых значений. Вы можете указать требуемый метод сортировки для всей записи или для каждого поля . Если вы не указываете разделитель полей, то используются пробелы или символы табуляции. Во втором примере листинга 14 сортировка первого поля выполняется по числовым значениям, а сортировка второго поля – с использованием схемы упорядочивания (в алфавитном порядке). Также показан пример использования опции -u для удаления повторяющихся строк.

Листинг 14. Сортировка по символьным и числовым значениям
$ cat text1 | tr " " "\t" | sort - text2 10 apple 1 apple 2 pear 3 banana 3 banana 9 plum $ cat text1|tr " " "\t"|sort -u -k1n -k2 - text2 1 apple 2 pear 3 banana 9 plum 10 apple

Заметьте, что в списке все равно присутствуют две строки со словом "apple", поскольку проверка уникальности выполнялась по всем ключам сортировки (в нашем случае это k1n и k2). Подумайте, какие команды нужно изменить или добавить в конвейер в последнем примере, чтобы исключить дублирование слова "apple".

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

Листинг 15. Использование команды uniq
$ cat text1|tr " " "\t"|sort -k2 - text2|uniq -f1 10 apple 3 banana 2 pear 9 plum

В этом примере сортировка выполнялась с использованием схемы упорядочивания, поэтому команда uniq оставила запись "10 apple", а не "1 apple". Вы можете добавить сортировку первого поля по числовым значениями и посмотреть, что изменится в этом случае.

Команды cut, paste и join

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

Листинг 16. Использование команды cut
$ cut -f1-2 --output-delimiter=" " text2 9 plum 3 banana 10 apple

Команда paste вставляет (склеивает) строки из двух или более файлов, размещая их рядом (подобно тому, как команда pr объединяет файлы с помощью опции -m). В листинге 17 показан результат применения этой команды к нашим текстовым файлам.

Листинг 17. Склеивание файлов
$ paste text1 text2 1 apple 9 plum 2 pear 3 banana 3 banana 10 apple

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

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

Листинг 18. Объединение файлов по совпадающим полям
$ sort -n text2|join -j 1 text1 - 3 banana banana join: file 2 is not in sorted order

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

Мы использовали опцию -j 1 для объединения по первому полю в каждом файле. Для каждого файла можно указать отдельное поле, по которому будет выполняться объединение. Например, можно объединить поле 3 в одном файле с полем 10 другого файла.

Давайте создадим еще один файл, text5, выполнив сортировку файла text1 по второму полю (имя фрукта), а затем заменив пробелы на символы табуляции. Если теперь мы отсортируем файл text2 по второму полю и объединим его с файлом text5 по этому же полю, то получим два совпадения (apple и banana). Это объединение показано в листинге 19.

Листинг 19. Объединение файлов по совпадающим полям
$ sort -k2 text1|tr " " "\t">text5 $ sort -k2 text2 | join -1 2 -2 2 text5 - apple 1 10 banana 3 3

Редактор Sed

Sed (s tream ed itor) – это потоковый редактор. Ему посвящено несколько статей Web-сайта developerWorks, а также множество книг (см. раздел ). Sed является чрезвычайно мощным инструментом, а круг решаемых им задач ограничен лишь вашим воображением. Этот небольшой обзор должен пробудить ваш интерес к sed, хотя он не является полным и всесторонним.

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

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

В листинге 20 показаны три простых сценария sed. В первом сценарии используется команда s (substitute – замена) для замены в каждой строке символа "a" в нижнем регистре на этот же символ в верхнем регистре. В первом примере выполняется замена только первого символа "a", поэтому во втором примере мы добавили флаг "g" (global – глобальный), благодаря которому, будет выполняться замена всех найденных вхождений этого символа. В третьем сценарии мы используем команду d (delete – удалить) для удаления строки. В нашем примере мы использовали адрес 2, чтобы показать, что необходимо удалить только строку с этим номером. Мы разделяем команды точкой с запятой (;) и используем глобальную замену символов "a" на "A", как это было сделано во втором примере.

Листинг 20. Первые шаги по работе со сценариями sed
$ sed "s/a/A/" text1 1 Apple 2 peAr 3 bAnana $ sed "s/a/A/g" text1 1 Apple 2 peAr 3 bAnAnA $ sed "2d;$s/a/A/g" text1 1 apple 3 bAnAnA

Помимо работы с отдельными строками, sed может работать с диапазонами строк. Начало и конец диапазона разделяются запятой (,) и могут определяться в виде номера строки, регулярного выражения или знака доллара ($), означающего конец файла. Зная адрес или диапазон адресов, вы можете сгруппировать несколько команд, заключив их в фигурные скобки { и }; таким образом, эти команды будут работать только с теми строками, которые указаны в диапазоне. В листинге 21 показано два примера глобальной замены, которая применяется только к последним двум строкам нашего файла. Также приведен пример использования опции -e для добавления нескольких команд в сценарий.

Листинг 21. Адреса в sed
$ sed -e "2,${" -e "s/a/A/g" -e "}" text1 1 apple 2 peAr 3 bAnAnA $ sed -e "/pear/,/bana/{" -e "s/a/A/g" -e "}" text1 1 apple 2 peAr 3 bAnAnA

Сценарии sed можно сохранять в виде файлов. Скорее всего, вы захотите использовать эту возможность для наиболее часто используемых сценариев. Вспомните команду tr , которую мы использовали для изменения пробелов в файле text1 на символы табуляции. Давайте теперь сделаем то же самое с помощью сценария sed, сохраненного в файле. Для создания файла мы используем команду echo . Результаты представлены в листинге 22.

Листинг 22. Короткая программа sed
$ echo -e "s/ /\t/g">sedtab $ cat sedtab s/ / /g $ sed -f sedtab text1 1 apple 2 pear 3 banana

Существует множество подобных коротких сценариев; ссылки на некоторые из них вы можете найти в разделе .

В нашем последнем примере сначала используется команда = для вывода номеров строк, а затем выполняется фильтрация полученного вывода с помощью sed (в результате мы получим такой же эффект, как от использования команды nl для нумерации строк). В листинге 23 с помощью команды = выводятся номера строк, затем с помощью команды N вторая строка ввода считывается в область шаблонов и, наконец, между двумя строками в области шаблонов удаляется символ новой строки (/n).

Листинг 23. Нумерация строк с помощью sed
$ sed "=" text2 1 9 plum 2 3 banana 3 10 apple $ sed "=" text2|sed "N;s/\n//" 19 plum 23 banana 310 apple

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

Листинг 24. Нумерация строк с помощью sed, второй подход
$ cat text1 text2 text1 text2>text6 $ ht=$(echo -en "\t") $ sed "=" text6|sed "N > s/^/ / > s/^.*\(......\)\n/\1$ht/" 1 1 apple 2 2 pear 3 3 banana 4 9 plum 5 3 banana 6 10 apple 7 1 apple 8 2 pear 9 3 banana 10 9 plum 11 3 banana 12 10 apple

Вот, что было сделано в этом примере:

  1. Сначала с помощью команды cat мы создали файл, содержащий 12 строк из двух копий файлов text1 и text2 (если бы количество строк оказалось меньше 10, т. е. все числа были бы одного порядка, то не было бы никакого смысла в их форматировании).
  2. В командном интерпретаторе bash клавиша табуляции используется для завершения команды, поэтому удобно иметь заранее определенный символ табуляции для использования в тех случаях, когда он вам потребуется. Для этого с помощью команды echo мы сохранили символ табуляции в переменной окружения "ht".
  3. Мы создали поток, содержащий номера строк и следующие за ними строки с данными, как мы делали это раньше, и отфильтровали его с помощью второй копии sed.
  4. Мы считали вторую строку в область шаблонов.
  5. В начале области шаблонов (обозначаемой символом ^) мы добавили к номеру строки префикс, состоящий из шести пробелов.
  6. Наконец, мы применили выравнивание с помощью разделителя, содержащего последние шесть символов и символ табуляции, и теперь в номера строк в выводе будут выровнены по первым шести символам. Обратите внимание на то, что в левой части команды "s" используются конструкции "\(" и "\)" для отметки символов, которые мы хотим использовать в правой части. В правой части мы ссылаемся на первый (и единственный в нашем примере) такой набор символов с помощью /1. Заметьте, что наша команда заключена в двойные кавычки ("), поэтому эта подстановка будет выполнена для переменной $ht.

Последняя (четвертая) версия редактора sed содержит документацию в формате info и включает множество превосходных примеров. В более старой версии, 3.02, эти возможности отсутствуют. Узнать версию редактора GNU sed можно с помощью команды sed --version .