Жанр: Учеба

Приемы профессиональной работы в Unix

сторінка №22

отите использовать команду UNIX'а write. Посмотрев на права доступа к
файлу устройства пользователя, вы можете сказать, имеется ли у вас
возможность записать текст на его экран. Некоторые пользователи, которые
не хотят, чтобы их прерывали, закрывают право записи на их терминал,
выполняя команду "mesg n". Вопрос о праве записи касается любого
способа посылки текста в другой файл, а не только с использованием команды
write. Право записи также защищает от таких вещей, как "echo
hello " /dev/tty00".

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

Например, мы хотим указать каждого пользователя. Мы используем
опцию -f. Опция -f устанавливает в качестве режима отображения режим
указания. Если мы поместим опцию -w справа от -f, как в команде "whox
-f -w", то установится режим записи на терминал. Команда whox будет
считать, что вы вообще не указывали опцию -f. На самом деле это не
представляет большую проблему, если вы знаете, что делает каждая опция.
Случайно смешивая их в одной команде, вы можете получить несколько
странные выходные данные.

ПРИМЕРЫ

1. $ sh -x whox -x

Запуск интерпретатора shell в отладочном режиме выполнения, подача
ему командного файла whox в качестве данных, передача опции -x для
whox. Отладочный режим показывает присвоение значений переменным и вызовы
команд. (Мы видели это ранее.)

2. $ whox -n -x

Печать выходных данных команды who, отсортированных по именам и
выдача дополнительных данных.

ПОЯСНЕНИЯ

В строках 4-10 выполняется инициализация переменных. Переменная
XTRA устанавливается в значение "no". Эта переменная используется для
построения командной строки при использовании опции -x. Установка XTRA
в значение "no" означает, что действие по умолчанию - не получать дополнительную
информацию.

Умолчанием для сортировки является сортировка по времени регистрации.
Это указывается сортировкой по колонке, стоящей после второй
(+2) и игнорированием ведущих пробелов (-b) в строке 5. Такой же синтаксис
применен ниже с опцией -t. Опция -t здесь лишняя, но она делает
более понятной командную строку. Опция -n также изменяет синтаксис
сортировки, чтобы просматривать первую колонку, которая является
списком имен.

Строка 6 инициализирует обычный режим отображения, которым является
печать стандартного выхода команды who. Если присутствуют другие
опции, соответственно изменяется переменная DISPLAY.

Строки 8,9 и 10 инициализируют некоторые переменные для команд
вырезки, что делает более компактными последующие команды. Если некоторые
командные строки оказываются слишком длинными, вы можете поместить
нужный текст в переменные и подставить их при необходимости.
Переменная CUT1 выглядит так, как будто она должна работать, но она не
работает в моей системе. Почему она не работает, объясняется ниже.
Просто запомните, что эта строка никогда не используется в данной
программе. Мы пока оставляем ее, чтобы поговорить о ней позже. Вы можете
убрать ее, если хотите.

Строки 12-35 обрабатывают аргументы командной строки. Цикл for
подставляет в переменную ARG каждый параметр по порядку и выполняет
оператор case по значению ARG.

Если опцией является -f, строка 15 изменяет переменную DISPLAY в
режим указания. Она также подставляет в переменную COMMAND команду
finger, которая выполнится в следующем цикле. Причина, по которой нам
нужно иметь переменную, содержащую команду, заключается в том, что
данный цикл является общим циклом, применяемым для двух разных целей.
Для того чтобы один и тот же цикл справился с двумя различными задачами,
мы помещаем эти задачи в переменную и выполняем эту переменную.
Это значительно сокращает общее количество текста, хотя привносит некоторую
дополнительную работу. Обратите внимание в строке 16, что символ
$ экранирован в операторе присваивания. Это необходимо, ведь мы
хотим, чтобы переменная COMMAND содержала символьную строку $NAME, а
не значение, которое имеет переменная NAME после присваивания. Значение
NAME расшифровывается в цикле во время его выполнения.

Строка 17 обрабатывает опцию -n. Все, что здесь требуется - изменить
способ сортировки выхода команды who, чтобы отразить порядок по
именам. Поскольку имя находится в первой колонке выхода команды who, а
команда sort сортирует по умолчанию по первой колонке, то используется
команда sort без опций.

Строка 18 обрабатывает опцию -m для передачи почтовых сообщений.
Здесь мы должны изменить режим отображения на почтовый. Все, что нужно
для этого, находится в цикле mail, и не требуется инициализировать никакие
переменные.

Строки 19 и 20 справляются с опцией -p. Опция паролей изменяет
режим отображения на парольный режим и устанавливает команду, которую
мы вызываем, находясь в общем цикле. В данном случае мы используем команду
grep для получения парольной записи из файла /etc/passwd. Обратите
внимание, что в строке 20 мы используем внутренние двойные кавычки.
Для этого мы вынуждены экранировать их символами обратной косой
черты. Напомним, что обратная косая черта используется для отмены специального
значения особых shell-символов.

Строка 21 управляет опцией -t. Как уже упоминалось ранее, опция
-t в действительности не требуется в данной программе. Поскольку она
является умолчанием, требуемые для нее действия уже были предприняты в
начале программы - была выполнена точно такая же инициализация. Синтаксис
команды sort точно такой же, как и в строке 5.

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

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

Строка 24 - это улавливатель для обработки ошибок. Символ * соответствует
любому символу, который не был распознан ранее. Печатается
сообщение об ошибке и синтаксическая подсказка, и whox завершается.

Строки 37-43 устанавливают переменные, используемые в опции дополнительной
информации. Строка 37 проверяет, установлена ли переменная
XTRA в состояние "yes", что имеет место только тогда, когда в командной
строке имелась опция -x. Если это так, то в переменную EXTRA
заносится много всяких вещей, которые мы рассмотрим позже. В противном
случае в переменную EXTRA заносится пустая строка, так что она никак
не проявляется на стадии фактического выполнения.

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

Строки 38-41 вставлены внутрь переменной EXTRA. Это сделано путем
взятия в двойные кавычки всех четырех строк. Все специальные символы,
которые должны быть частью данных в этой переменной, должны быть экранированы
символами обратной косой черты. В строке 38 в переменную
EXTRA заносится символ конвейера (|) и начало цикла while. В конце
строки 38 имеется символ косой черты, указывающий интерпретатору
shell, что присваивание продолжается после символа конца строки (возврата
каретки или перевода строки).


Строка 39 присваивает переменной NAME значение поля, вырезанного
из данных, читаемых в цикле while. Напомним, что весь данный оператор
помещается внутрь переменной EXTRA. Когда я выше упоминал, что в строке
с переменной CUT1 есть проблемы, то как одно из таких проблемных
мест я имел в виду именно это. Когда я попытался использовать переменную
CUT1 в этом операторе вместо указания команды cut, shell не смог
правильно распознать этот оператор. Одинарные кавычки, отмечающие символ-разделитель
для вырезки, не были распознаны. В результате команда
cut считала, что символом-разделителем является символ ' и после этого
аварийно завершалась, поскольку второй символ ' представлял собой недопустимое
описание списка для опции -f. Строка с опцией -f шла позже,
но команда cut этого никогда не узнавала, поскольку аварийно завершалась
до этого. Когда я заменил переменную CUT1 просто командой cut,
эта проблема исчезла.

Давайте рассмотрим, как я отлаживал эту часть. Я использовал
shell с опцией -x, поэтому я мог следить за тем, что происходит. Как
вы можете видеть, когда переменная CUT1 была инициализирована, одинарные
кавычки находились все еще в операторе, но когда выполнялась
настоящая команда cut, одинарные кавычки уходили при синтаксическом
расширении. Для генерации такого списка данных я выполнил следующий
вызов: sh -x whox -x. Вот что я увидел:

XTRA=no
SORT=sort -b +2
DISPLAY=norm
CUT1=cut -d' ' -f1 "- Одинарные кавычки все еще здесь.
Основная проблема.
CUT5=cut -d: -f5
CUT6=cut -d: -f6
XTRA=yes
+ who
+ read LINE
+ sort -b +2
+ echo russ console Jun 20 14:11
+ cut -d -f1 "- Теперь выполняется правильно.
Кавычек нет.

Это сокращенная распечатка. Она показывает, что когда выполнялась
команда cut, она не имела одинарных кавычек. Когда же запускалась переменная
CUT1, она имела одинарные кавычки. Я не мог представить, как
избавиться от кавычек, поэтому я просто вставил вызов самой команды
cut обратно на это место. Может быть какой-нибудь молодой растущий
мастер сможет себе это представить.

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

Цикл, выполняющий такое же присваивание, имеет такой вид при
обычном стиле записи на языке shell:

| while read LINE
do
NAME=`echo $LINE | cut -d' ' -f1`
ENTRY=`grep "^$NAME:" /etc/passwd`
echo "$LINE\t\`echo $ENTRY|$CUT6\`\t\`echo $ENTRY|$CUT5\`\"
done

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

Строки 45-60 - это оператор case, который реализует различные режимы
отображения. Строка 46 выполняет обычный режим отображения команды
who. Поскольку в обычном режиме имеется возможность использовать
переменную EXTRA, нам необходимо произвести повторный разбор командной
строки командой eval, чтобы эта переменная приняла свое истинное значение
во время исполнения. Обратите внимание, что в команде eval имеются
кавычки, заключающие всю командную строку. Это необходимо потому,
что вся строка является одним набором входных данных для команды eval.
Без кавычек команда eval не работала бы. Переменная EXTRA не подвергается
повторному разбору.

Строки 47-50 управляют режимами указания пользователя и выдачи
информации из файла паролей. Оба эти режима используют один и тот же
цикл. Цикл for использован для установки переменной NAME в значение
первого поля каждой строки, полученной от команды who. Для каждого
имени, вырезанного из результата работы команды who, выполняется повторный
синтаксический разбор командой eval переменной COMMAND (которая
была установлена в операторе case, выполнявшем разбор аргументов). Тем
самым повторно анализируются и выполняются команды, находящиеся в переменной
COMMAND. Для режима указания пользователя переменная COMMAND
содержит команду finger, а для режима паролей в COMMAND хранится команда
grep.


Строки 51-58 похожи на режим указания пользователя. Этот цикл тоже
требует имена от команды who, но вместо использования оператора for
мы используем метод прямой пересылки по конвейеру. Результат работы
команды who по конвейеру передается команде cut (переменная CUT1 и
здесь бы не работала), которая по конвейеру передает данные в цикл
чтения while. Обратите внимание, что в этом месте нет никакой сортировки.
По умолчанию результат команды who выводится в порядке номеров
терминальных устройств. Я не думаю, однако, что порядок вывода этих
данных имеет большое значение.

Для каждого имени пользователя выводится запрос о том, хотите ли
вы передать ему почтовое сообщение. При чтении ответа в строке 54
должна быть использована команда UNIX'а line. Почему? Потому что весь
цикл использует оператор read для чтения имен. Оператор read читает
только со стандартного ввода, который в данном случае привязан к конвейеру.
Для получения входных данных с клавиатуры мы должны использовать
команду line, которая получает их из файла /dev/tty. Это распространенный
способ чтения данных с клавиатуры из переадресованного
цикла.

Строка 55 проверяет, является ли ответом символ y. Если да, вызывается
команда UNIX'а mail, и снова ввод переадресовывается из файла
/dev/tty (поскольку строки почтового сообщения мы должны вводить с
клавиатуры.) В данном случае мы фактически переадресовываем стандартный
ввод для вызова подчиненного shell-процесса, выполняющего команду
mail. Без выполнения переадресации команда mail читает из файла
/dev/null, что нарушает выполнение всего цикла whox.

Строка 59 управляет режимом показа возможности записи на терминал.
Цель здесь такова - использовать одну команду ls и, применяя подчиненный
процесс, извлечь файлы терминальных устройств из выходных
данных команды who. Эти файлы являются вторым полем результата команды
who. Сначала запускается команда who, которая по конвейеру передает
свои данные команде sed.

Затем sed использует команду подстановки для отбрасывания всего,
кроме того, что ограничено символами \( и \). Последующая часть команды
подстановки ссылается на этот ограниченный участок с помощью обозначения
\1. Используя символ . как соответствующий любому символу
распечатки, мы должны всего лишь посчитать столбцы, которые нам нужно
вырезать. Кроме того, имена устройств в команде who не имеют префикса
/dev/, который нам необходим. Команда sed вставляет его перед текстом,
вырезанным из команды who. В результате команде ls дается список полных
маршрутных имен ко всем файлам устройств зарегистрированных пользователей.
Затем это выводится на экран.

ЗАЩИТА ЛИЧНОЙ ИНФОРМАЦИИ

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

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


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

В данном разделе мы рассмотрим инструментальные средства acme,
inuse и lock. Acme - это препроцессор к команде UNIX'а acctcom.
Acctcom выполняет довольно неплохую работу по отображению учетной информации,
но некоторые опции требуется указывать все время. Acme устанавливает
их для нас. Напомним, что учетные записи хранятся в виде
структуры, а не в текстовом виде, и поэтому мы заставляем acctcom показывать
их для нас.

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

Последнее средство, lock, используется для блокирования и разблокирования
прав доступа к файлу и является на самом деле простым интерфейсом
с командой chmod.

---------------------------------------------------------------------------

ИМЯ: acme
---------------------------------------------------------------------------

acme Отображение учетной информации обо мне

НАЗНАЧЕНИЕ

Генерирует опции, необходимые для вывода на экран информации обо
мне, которая хранится в учетном файле.

ФОРМАТ ВЫЗОВА

acme [-l] [-u]

ПРИМЕР ВЫЗОВА

acme -u Выводит всю учетную информацию о пользователе с
именем $LOGNAME

ТЕКСТ ПРОГРАММЫ

1 :
2 # @(#) acme v1.0 Give accounting info on me Author: Russ Sage
2а Дать учетную информацию обо мне

4 if [ "$1" != "-l" -a "$1" != "-u" ]
5 then echo "usage: acme [-l] [-u]" "&2
6 echo " -l for ttyline" "&2
7 echo " -u for user name" "&2
8 exit 0
9 fi

11 OPT=""
12 for ARG in $*
13 do
14 case $ARG in
15 -l) OPT="$OPT -l `basename \`tty\``";;
16 -u) OPT="$OPT -u $LOGNAME";;
17 *) OPT="$OPT $ARG";;
18 esac
19 done

21 echo "acctcom $OPT"
22 acctcom $OPT

ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ

ARG Каждое значение, указанное в командной строке
LOGNAME Переменная среды, содержащая мое регистрационное имя
OPT Объединенный список всех опций и их аргументов

ОПИСАНИЕ

ЗАЧЕМ НАМ НУЖЕН КОМАНДНЫЙ ФАЙЛ acme?

Большинство больших систем UNIX запускают стандартное программное
обеспечение для сбора учетной информации об использовании системы. Результаты
учетных транзакций передаются обычно в файл /usr/adm/pacct.
Фактически сбор учетной информации выполняется ядром системы. Каждый
раз при завершении процесса программы сбора учетной информации в ядре
производят одну запись. Переключателем, который включает и выключает
эту операцию, является acct(2). Команды пользовательского уровня также
взаимодействуют с системным вызовом (accton(1M)) и печатают результаты
сбора учетной информации (acctcom(1)).

Теперь, когда мы знаем, где находятся учетные записи и как они
туда попадают, нам нужно напечатать эту информацию. Acctcom может печатать
таблицы с информацией, но вам необходимо знать, какой использовать
индекс. Просмотр может производится по номеру терминальной линии
(это полезно, если идентификатор процесса был изменен командой
setuid), по имени пользователя, по группе, по времени и т.д. Я наиболее
часто использую опции поиска информации по номеру линии терминала
и по имени пользователя. С их помощью вы можете получить список всех
основных данных, имеющих отношение к вам. Когда вы вызываете acctcom с
этими опциями, вам необходимо указать дополнительную информацию, такую
как имя вашего терминала и ваше пользовательское имя. Было бы хорошо,
если бы мы могли уменьшить количество нажатий на клавиши и объем вычислений,
требуемых для получения информации. Для этого и предназначен
acme.

ЧТО ДЕЛАЕТ acme?

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

Команда acctcom имеет много опций. В действительности мы используем
одну или две, но зато используем их часто. Двумя опциями, которые
понимает acme, являются -l и -u. Когда указана опция -l, acme получает
имя вашего терминала и помещает его в командную строку. Если указана
опция -u, acme получает ваше пользовательское имя и тоже вставляет его
в командную строку. Время от времени используются другие опции для
бавления специфической информации или небольшого изменения выходного
формата. Для того чтобы была возможность использовать другие опции команды
acctcom, acme включает в командную строку, формируемую для
fcctcom, любые дополнительные корректные опции acctcom, переданные в
командной строке для acme. Таким образом, acme поддерживает базовые
возможности, а кроме того позволяет вам подгонять команду под ваш
вкус.

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

ПРИМЕРЫ

1. $ acme

Выдача ВСЕХ моих учетных данных. Это последовательный список всех
команд, которые были запущены начиная с момента загрузки по настоящее
время. Счастливого чтения!

2. $ acme -u -b

Печать в обратном порядке всех учетных записей с моим пользовательским
именем. Обратный порядок означает - от самой последней из
предыдущих команд до моей первой команды.

3. $ acme -l

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

ПОЯСНЕНИЯ

В строках 4-9 выполняется проверка на наличие ошибок. Если первый
позиционный параметр не -l и не -u, то это ошибка. Выводится сообщение
об этом и программа завершается.

В строке 11 переменная OPT инициализируется пустой строкой. Эта
переменная содержит все дополнительные опции acctcom и их аргументы.

Строки 12-19 представляют собой цикл for, который повторяется по
всем позиционным параметрам. Каждый аргумент сверяется в операторе
case с допустимыми опциями. Если опцией является -l (строка 15), в переменную
OPT заносится то значение, которое она уже имеет, опция -l и
добавляется имя терминального устройства, полученное от команды UNIX'а
tty. Команда tty выводит и префикс /dev, который не нужен. Для того
чтобы избавиться от этого префикса, мы берем из этой символьной строки
только основное имя.

Если указана опция -u, в переменную OPT добавляется -u и наше регистрационное
имя. Если аргументом являются любые другие данные, то
они просто добавляются в переменную OPT. Поступая таким образом, мы
можем передать в командной строке acme другие опции команде acctcom.
Обратите внимание, что здесь не выполняется проверка на ошибки в аргументах
командной строки. Вы можете ввести неверное значение, которое
нарушит работу команды acctcom. Однако это та цена, которую мы вынуждены
платить за гибкость при передаче аргументов в командной строке,
иначе нам придется значительно увеличивать текст командного файла.

После того обработки всех опций строка 21 выводит на экран командную
строку, которая должна быть выполнена, так что мы знаем, что
мы задавали. В строке 22 выполняется сама команда acctcom. Выходной
результат соответствует описанию acctcom(1).

---------------------------------------------------------------------------

ИМЯ: inuse
---------------------------------------------------------------------------

inuse Запретить использование терминала

НАЗНАЧЕНИЕ

Блокирует ваш терминал путем перевода в состояние занятости. Если
кто-либо попытается вторгнуться, вы это заметите.

ФОРМАТ ВЫЗОВА

inuse

ПРИМЕРЫ ВЫЗОВА

inuse Перевод терминала в состояние занятости
mypasswd Вводится мой пароль, но не отображается на экран

ТЕКСТ ПРОГРАММЫ

1 :
2 # @(#) inuse v1.0 Disable terminal and alert if used Author: Russ Sage
2а Запретить использование терминала и сообщить о попытке использования

4 trap "echo you\'re BUSTED!!; stty echo; kill $$" 2 15

6 PATH=/bin:/usr/bin
7 SECRET="secret"

9 stty -echo
10 echo "Lock string: \c"
11 read BUF1
12 echo

14 while :
15 do
16

Список сторінок

Поділитися у соцмережах

☏ Замовлення реклами: +3805044-68-872

© Асоціація електронних бібліотек України

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