ar
Утилита создания и обслуживания архивов, главным образом применяется к двоичным файлам библиотек.
rpm
Red Hat Package Manager, или rpm -- набор утилит, предназначенных для построения и обслуживания пакетов программного обеспечения как в исходном коде, так и в собранном (откомпилированном) виде. Среди всего прочего, включает в себя утилиты, производящие установку ПО, проверку зависимостей пакетов и проверку их целостности.
Самый простой вариант установки ПО из rpm -- выполнить команду rpm - i package_name. rpm.
| Команда rpm - qa выдаст полный список всех установленных rpm-пакетов в данной системе. Команда rpm - qa package_name выведет только пакет(ы) с именем, содержащим комбинацию символов package_name. bash$ rpm - qa redhat-logos-1.1.3-1 glibc-2.2.4-13 cracklib-2.7-12 dosfstools-2.7-1 gdbm-1.8.0-10 ksymoops-2.4.1-1 mktemp-1.5-11 perl-5.6.0-17 reiserfs-utils-3.x.0j-2 ... bash$ rpm - qa docbook-utils docbook-utils-0.6.9-2 bash$ rpm - qa docbook | grep docbook docbook-dtd31-sgml-1.0-10 docbook-style-dsssl-1.64-3 docbook-dtd30-sgml-1.0-10 docbook-dtd40-sgml-1.0-11 docbook-utils-pdf-0.6.9-2 docbook-dtd41-sgml-1.0-10 docbook-utils-0.6.9-2 |
cpio
Специализированная утилита архивации и копирования (copy input and output). Используется все реже и реже, поскольку вытесняется более мощным архиватором tar/gzip. Наиболее употребительна для таких операций, как перемещение дерева каталогов.
Пример 12-22. Пример перемещения дерева каталогов с помощью cpio
#!/bin/bash
# Копирование дерева каталогов с помощью cpio.
ARGS=2
E_BADARGS=65
if [ $# - ne "$ARGS" ]
then
echo "Порядок использования: `basename $0` source destination"
exit $E_BADARGS
fi
source=$1
destination=$2
find "$source" - depth | cpio - admvp "$destination"
# Информацию по ключам утилиты cpio вы найдете в страницах руководства "man cpio".
exit 0
rpm2cpio
Эта утилита конвертирует rpm-пакет в архив cpio.
Пример 12-23. Распаковка архива rpm
#!/bin/bash
# de-rpm. sh: Распаковка архива 'rpm'
: ${1?"Порядок использования: `basename $0` target-file"}
# Сценарию должно быть передано имя архива 'rpm'.
TEMPFILE=$$.cpio # Временный файл с "уникальным" именем.
# $$ -- PID процесса сценария.
rpm2cpio < $1 > $TEMPFILE # Конверсия из rpm в cpio.
cpio --make-directories - F $TEMPFILE - i # Рапсковка cpio-архива.
rm - f $TEMPFILE # Удаление cpio-архива.
exit 0
# Упражнение:
# Добавьте проверку на: 1) Существование "target-file"
#+ 2) Действительно ли "target-file" является rpm-архивом.
# Подсказка: используйте комсанду 'file'.
Сжатие
gzip
Стандартная GNU/UNIX утилита сжатия, заменившая более слабую, и к тому же проприетарную, утилиту compress. Соответствующая утилита декомпрессии (разжатия) -- gunzip, которая является эквивалентом команды gzip - d.
Для работы со сжатыми файлами в конвейере используется фильтр zcat, который выводит результат своей работы на stdout, допускает перенаправление вывода. Фактически это та же команда cat, только приспособленная для работы со сжатыми файлами (включая файлы, сжатые утилитой compress). Эквивалент команды zcat -- gzip - dc.
| В некоторых коммерческих версиях UNIX, команда zcat является синонимом команды uncompress - c, и не может работать с файлами, сжатыми с помощью gzip. |
См. также Пример 7-7.
bzip2
Альтернативная утилита сжатия, обычно дает более высокую степень сжатия (но при этом работает медленнее), чем gzip, особенно это проявляется на больших файлах. Соответствующая утилита декомпрессии -- bunzip2.
| В современные версии tar добавлена поддержка bzip2. |
compress, uncompress
Устаревшие проприетарные утилиты для работы с архивами, входящие в состав некоторых коммерческих дистрибутивов UNIX. В последнее время вытесняются более мощной утилитой gzip. Linux-дистрибутивы, как правило, включают в свой состав эти утилиты для обратной совместимости, однако gunzip корректно разархивирует файлы, обработанные с помощью compress.
| Утилита znew предназначена для преобразования compress-архивов в gzip-архивы. |
sq
Еще одна утилита-фильтр сжатия, которая обслуживает только отсортированные списки слов. Использует стандартный, для фильтров, синтаксис вызова -- sq < input-file > output-file. Быстрая, но не такая эффективная как gzip. Соответствующая ей утилита декомпрессии называется unsq, синтаксис вызова аналогичен утилите sq.
| Вывод от sq может быть передан по конвейеру утилите gzip, для дальнейшего сжатия. |
zip, unzip
Кроссплатформенная утилита архивирования и сжатия, совместимая, по формату архивного файла, с утилитой DOS -- pkzip. exe. "Zip"-архивы, по-моему, более приемлемый вариант для обмена данными через Internet, чем "tarballs" (тарболлы, или tar-архивы).
unarc, unarj, unrar
Этот набор утилит предназначен для распаковки архивов, созданных с помощью DOS архиваторов -- arc. exe, arj. exe и rar. exe.
Получение сведений о файлах
file
Утилита идентификации файлов. Команда file file-name верне тип файла file-name, например, ascii text или data. Для этого она анализирует сигнатуру, или магическое число и сопоставляет ее со списком известных сигнатур из /usr/share/magic, /etc/magic или /usr/lib/magic (в зависимости от дистрибутива Linux/UNIX).
-f -- ключ пакетного режима работы утилиты file, в этом случае утилита принимает список анализируемых имен файлов из заданного файла. Ключ - z используется для анализа файлов в архиве.
bash$
file test. tar. gz
test. tar. gz: gzip compressed data, deflated, last modified: Sun Sep 16 13:34:51 2001, os: Unix
bash
file - z test. tar. gz
test. tar. gz: GNU tar archive (gzip compressed data, deflated, last modified: Sun Sep 16 13:34:51 2001, os: Unix)
Пример 12-24. Удаление комментариев из файла с текстом программы на языке C
#!/bin/bash
# strip-comment. sh: Удаление комментариев (/* COMMENT */) из исходных текстов программ на языке C.
E_NOARGS=65
E_ARGERROR=66
E_WRONG_FILE_TYPE=67
if [ $# - eq "$E_NOARGS" ]
then
echo "Порядок использования: `basename $0` C-program-file" >&2 # Вывод сообщения на stderr.
exit $E_ARGERROR
fi
# Проверка типа файла.
type=`eval file $1 | awk '{ print $2, $3, $4, $5 }'`
# "file $1" -- выводит тип файла...
# затем awk удаляет первое поле -- имя файла...
# после этого результат записывается в переменную "type".
correct_type="ASCII C program text"
if [ "$type" != "$correct_type" ]
then
echo
echo "Этот сценарий работает только с исходными текстами программ на языке C."
echo
exit $E_WRONG_FILE_TYPE
fi
# Довольно замысловатый сценарий sed :
#
sed '
/^\/\*/d
/.*\/\*/d
' $1
#
# Если вы потратите несколько часов на изучение основ sed, то он станет немного понятнее.
# Следовало бы добавить еще обработку
#+ комментариев, расположенных в одной строке с кодом.
# Оставляю это вам, в качестве упражнения.
# Кроме того, этот сценарий удалит все строки, которые содержат комбинации символов "*/" или "/*",
# не всегда желаемый результат.
exit 0
#
# Строки, расположенные ниже не будут исполнены из-за стоящей выше команды 'exit 0'.
# Stephane Chazelas предложил другой, альтернативный вариант:
usage() {
echo "Порядок использования: `basename $0` C-program-file" >&2
exit 1
}
WEIRD=`echo - n - e '\377'` # или WEIRD=$'\377'
[[ $# - eq 1 ]] || usage
case `file "$1"` in
*"C program text"*) sed - e "s%/\*%${WEIRD}%g;s%\*/%${WEIRD}%g" "$1" \
| tr '\377\n' '\n\377' \
| sed - ne 'p;n' \
| tr - d '\n' | tr '\377' '\n';;
*) usage;;
esac
# Этот вариант, все еще некорректно обрабатывает такие строки как:
# printf("/*");
# или
# /* /* ошибочный вложенный комментарий */
#
# Для обработки специальных случаев (\", \\" ...) придется написать синтаксический анализатор
# (может быть с помощью lex или yacc?).
exit 0
which
Команда which command-xxx вернет полный путь к "command-xxx". Очень полезна для того, чтобы узнать -- установлена ли та или иная утилита в системе.
$bash which rm
/usr/bin/rm
whereis
Очень похожа на which, упоминавшуюся выше. Команда whereis command-xxx вернет полный путь к "command-xxx", но кроме того, еще и путь к manpage -- файлу, странице справочника по заданной утилите.
$bash whereis rm
rm: /bin/rm /usr/share/man/man1/rm.1.bz2
whatis
Утилита whatis filexxx отыщет "filexxx" в своей базе данных. Может рассматриваться как упрощенный вариант команды man.
$bash whatis whatis
whatis (1) - search the whatis database for complete words
Пример 12-25. Исследование каталога /usr/X11R6/bin
#!/bin/bash
# Что находится в каталоге /usr/X11R6/bin?
DIRECTORY="/usr/X11R6/bin"
# Попробуйте также "/bin", "/usr/bin", "/usr/local/bin", и т. д.
for file in $DIRECTORY/*
do
whatis `basename $file` # Вывод информации о файле.
done
exit 0
# Вывод этого сценария можно перенаправить в файл:
# ./what. sh >>whatis. db
# или включить постраничный просмотр на экране,
# ./what. sh | less
См. также Пример 10-3.
vdir
Вывод списка файлов в каталоге. Тот же эффект имеет команда ls -l.
Это одна из утилит GNU fileutils.
bash$
vdir
total 10
- rw-r--r-- 1 bozo bozo 4034 Jul 18 22:04 data1.xrolo
- rw-r--r-- 1 bozo bozo 4602 May 25 13:58 data1.xrolo. bak
- rw-r--r-- 1 bozo bozo 877 Decemployment. xrolo
bash
ls - l
total 10
- rw-r--r-- 1 bozo bozo 4034 Jul 18 22:04 data1.xrolo
- rw-r--r-- 1 bozo bozo 4602 May 25 13:58 data1.xrolo. bak
- rw-r--r-- 1 bozo bozo 877 Decemployment. xrolo
locate, slocate
Команда locate определяет местонахождение файла, используя свою базу данных, создаваемую специально для этих целей. Команда slocate -- это защищенная версия locate (которая может оказаться простым псевдонимом команды slocate).
$bash locate hickson
/usr/lib/xephem/catalogs/hickson. edb
readlink
Возвращает имя файла, на который указывает символическая ссылка.
bash$
readlink /usr/bin/awk
../../bin/gawk
strings
Команда strings используется для поиска печатаемых строк в двоичных файлах. Она выводит последовательности печатаемых символов, обнаруженных в заданном файле. Может использоваться для прикидочного анализа дамп-файлов (core dump) или для отыскания информации о типе файла, например для графических файлов неизвестного формата (например, strings image-file | more может вывести такую строчку: JFIF, что говорит о том, что мы имеем дело с графическим файлом в формате jpeg). В сценариях, вероятнее всего, вам придется использовать эту команду в связке с grep или sed. См. Пример 10-7 и Пример 10-9.
Пример 12-26. "Расширенная" команда strings
#!/bin/bash
# wstrings. sh: "word-strings" (расширенная команда "strings")
#
# Этот сценарий фильтрует вывод команды "strings" путем проверки на соответствие
#+ выводимых слов по файлу словаря.
# Таким способом эффективно "отсекается" весь "мусор",
#+ и выводятся только распознанные слова.
# =================================================================
# Стандартная проверка входных аргументов
ARGS=1
E_BADARGS=65
E_NOFILE=66
if [ $# - ne $ARGS ]
then
echo "Порядок использования: `basename $0` filename"
exit $E_BADARGS
fi
if [ ! - f "$1" ] # Проверка наличия файла.
then
echo "Файл \"$1\" не найден."
exit $E_NOFILE
fi
# =================================================================
MINSTRLEN=3 # Минимальная длина строки.
WORDFILE=/usr/share/dict/linux. words # Файл словаря.
# Можно указать иной
#+ файл словаря
#+ в формате -- "одно слово на строке".
wlist=`strings "$1" | tr A-Z a-z | tr '[:space:]' Z | \
tr - cs '[:alpha:]' Z | tr - s '\173-\377' Z | tr Z ' '`
# Трансляция вывода от 'strings' с помощью нескольких 'tr'.
# "tr A-Z a-z" -- перевод в нижний регистр.
# "tr '[:space:]'" -- конвертирует пробелы в символы Z.
# "tr - cs '[:alpha:]' Z" -- конвертирует неалфавитные символы в символы Z,
#+ и удаляет повторяющиеся символы Z.
# "tr - s '\173-\377' Z" -- Конвертирует все символы, с кодами выше 'z' в Z
#+ и удаляет повторяющиеся символы Z,
#+ эта команда удалит все символы, которые не были распознаны предыдущими
#+ командами трансляции (tr).
# Наконец, "tr Z ' '" -- преобразует все символы Z в пробелы,
#+ которые будут рассматриваться в качестве разделителя слов в цикле, приведенном ниже.
# Обратите внимание на технику многоуровневой обработки с помощью 'tr',
#+ каждый раз эта команда вызывается с различным набором аргументов.
for word in $wlist # Важно:
# переменная $wlist не должна заключаться в кавычки.
# "$wlist" -- не сработает.
# Почему?
do
strlen=${#word} # Дина строки.
if [ "$strlen" - lt "$MINSTRLEN" ] # Не рассматривать короткие строки.
then
continue
fi
grep - Fw $word "$WORDFILE" # Проверка слова по словарю.
done
exit 0
Сравнение
diff, patch
diff: очень гибкая утилита сравнения файлов. Она выполняет построчное сравнение файлов. В отдельных случаях, таких как поиск по словарю, может оказаться полезной фильтрация файлов с помощью sort и uniq перед тем как отдать поток данных через конвейер утилите diff. diff file-1 file-2 -- выведет строки, имеющие отличия, указывая -- какому файлу, какая строка принадлежит.
С ключом --side-by-side, команда diff выведет сравниваемые файлы в две колонки, с указанием несовпадающих строк. Ключи - c и - u так же служат для облегчения интерпретации результатов работы diff.
Существует ряд интерфейсных оболочек для утилиты diff, среди них можно назвать: spiff, wdiff, xdiff и mgdiff.
| Команда diff возвращает код завершения 0, если сравниваемые файлы идентичны и 1, если они отличаются. Это позволяет использовать diff в условных операторах внутри сценариев на языке командной оболочки (см. ниже). |
В общем случае, diff используется для генерации файла различий, который используется как аргумент команды patch. Ключ - e отвечает за вывод файла различий в формате, пригодном для использования с ed или ex.
patch: гибкая утилита для "наложения заплат". С помощью файла различий, сгенерированного утилитой diff, утилита patch может использоваться для обновления устаревших версий файлов. Это позволяет распространять относительно небольшие "diff"-файлы вместо целых пакетов. Распространение "заплат" к ядру стало наиболее предпочтительным методом распространения более новых версий ядра Linux.
patch - p1 <patch-file
# Применит все изменения из 'patch-file'
# к файлам, описанным там же.
# Так выполняется обновление пакетов до более высоких версий.
Наложение "заплат" на ядро:
cd /usr/src
gzip - cd patchXX. gz | patch - p0
# Обновление исходных текстов ядра с помощью 'patch'.
# Пример взят из файла "README",
# автор не известен (Alan Cox?).
| Кроме того, утилита diff в состоянии выполнять рекурсивный обход каталогов. bash$ diff - r ~/notes1 ~/notes2 Only in /home/bozo/notes1: file02 Only in /home/bozo/notes1: file03 Only in /home/bozo/notes2: file04 |
| Утилита zdiff сравнивает сжатые, с помощью gzip, файлы. |
diff3
Расширенная версия diff, которая сравнивает сразу 3 файла. В случае успеха возвращает 0, но, к сожалению, не дает никакой информации о результатах сравнения.
bash$
diff3 file-1 file-2 file-3
====
1:1c
This is line 1 of "file-1".
2:1c
This is line 1 of "file-2".
3:1c
This is line 1 of "file-3"
sdiff
Сравнение и/или редактирование двух файлов перед объединением их в один файл. Это интерактивная утилита, по своей природе, и из-за этого она довольно редко используется в сценариях.
cmp
Утилита cmp -- это упрощенная версия diff. В то время, как diff выводит подробную информацию об имеющихся различиях, утилита cmp лишь показывет номер строки и позицию в строке, где было встречено различие.
| Подобно команде diff, команда cmp возвращает код завершения 0, если файлы идентичны и 1, если они различны. Это позволяет использовать команду cmp в условных операторах. |
Пример 12-27. Пример сравнения двух файлов с помощью cmp.
#!/bin/bash
ARGS=2 # Ожидаются два аргумента командной строки.
E_BADARGS=65
E_UNREADABLE=66
if [ $# - ne "$ARGS" ]
then
echo "Порядок использования: `basename $0` file1 file2"
exit $E_BADARGS
fi
if [[ ! - r "$1" || ! - r "$2" ]]
then
echo "Оба файла должны существовать и должны быть доступны для чтения."
exit $E_UNREADABLE
fi
cmp $1 $2 &> /dev/null # /dev/null -- "похоронит" вывод от команды "cmp".
# cmp - s $1 $2 даст тот же результат ("-s" -- флаг "тишины" для "cmp")
# Спасибо Anders Gustavsson за замечание.
#
# Также применимо к 'diff', т. е., diff $1 $2 &> /dev/null
if [ $? - eq 0 ] # Проверка кода возврата команды "cmp".
then
echo "Файл \"$1\" идентичен файлу \"$2\"."
else
echo "Файл \"$1\" отличается от файла \"$2\"."
fi
exit 0
| Для работы с gzip файлами используется утилита zcmp. |
comm
Универсальная утилита сравнения. Работает с отсортированными файлами.
comm -options first-file second-file
comm file-1 file-2 -- вывод в три колонки:
· колонка 1 = уникальные строки для file-1
· колонка 2 = уникальные строки для file-2
· колонка 3 = одинаковые строки.
Ключи, подавляющие вывод в одной или более колонках.
· подавление вывода в колонку 1
· подавление вывода в колонку 2
· подавление вывода в колонку 3
· подавление вывода в колонки 1 и 2, и т. д.
Утилиты
basename
Выводит только название файла, без каталога размещения. Конструкция basename $0 -- позволяет сценарию узнать свое имя, то есть имя файла, который был запущен. Это имя может быть использовано для вывода сообщений, напрмиер:
echo "Порядок использования: `basename $0` arg1 arg2 ... argn"
dirname
Отсекает basename от полного имени файла и выводит только путь к файлу.
| Утилитам basename и dirname может быть передана любая строка, в качестве аргумента. Этот аргумент необязательно должен быть именем существующего файла (см. Пример A-8). |
Пример 12-28. Утилиты basename и dirname
#!/bin/bash
a=/home/bozo/daily-journal. txt
echo "Basename для /home/bozo/daily-journal. txt = `basename $a`"
echo "Dirname для /home/bozo/daily-journal. txt = `dirname $a`"
echo
echo "Мой домашний каталог `basename ~/`." # Можно указать просто ~.
echo "Каталог моего домашнего каталога `dirname ~/`." # Можно указать просто ~.
exit 0
split
Утилита разбивает файл на несколько частей. Обычно используется для разбиения больших файлов, чтобы их можно было записать на дискеты или передать по электронной почте по частям.
sum, cksum, md5sum
Эти утилиты предназначены для вычисления контрольных сумм. Контрольная сумма -- это некоторое число, вычисляемое исходя из содержимого файла, и служит для контроля целостности информации в файле. Сценарий может выполнять проверку контрольных сумм для того, чтобы убедиться, что файл не был изменен или поврежден. Для большей безопасности, рекомендуется использовать 128-битную сумму, генерируемую утилитой md5sum (message digest checksum).
bash$
cksum /boot/vmlinuz
1670054/boot/vmlinuz
bash$
md5sum /boot/vmlinuz
0f43eccea8f09e0a0b2b5cf1dcf333ba /boot/vmlinuz
Обратите внимание: утилита cksum выводит контрольную сумму и размер файла в байтах.
Пример 12-29. Проверка целостности файла
#!/bin/bash
# file-integrity. sh: Проверка целостности файлов в заданном каталоге
E_DIR_NOMATCH=70
E_BAD_DBFILE=71
dbfile=File_record. md5
# Файл для хранения контрольных сумм.
set_up_database ()
{
echo ""$directory"" > "$dbfile"
# Записать название каталога в первую строку файла.
md5sum "$directory"/* >> "$dbfile"
# Записать контрольные суммы md5 и имена файлов.
}
check_database ()
{
local n=0
local filename
local checksum
# #
# Возможно эта проверка и не нужна,
#+ но лучше перестраховаться сейчас, чем жалеть об этом потом.
if [ ! - r "$dbfile" ]
then
echo "Не могу прочитать файл с контрольными суммами!"
exit $E_BAD_DBFILE
fi
# #
while read record[n]
do
directory_checked="${record[0]}"
if [ "$directory_checked" != "$directory" ]
then
echo "Имя каталога не совпадает с записаным в файле!"
# Попытка использовать файл контрольных сумм для другого каталога.
exit $E_DIR_NOMATCH
fi
if [ "$n" - gt 0 ] # Не имя каталога.
then
filename[n]=$( echo ${record[$n]} | awk '{ print $2 }' )
# md5sum записывает в обратном порядке,
#+ сначала контрольную сумму, затем имя файла.
checksum[n]=$( md5sum "${filename[n]}" )
if [ "${record[n]}" = "${checksum[n]}" ]
then
echo "Файл ${filename[n]} не был изменен."
else
echo "ОШИБКА КОНТРОЛЬНОЙ СУММЫ для файла ${filename[n]}!"
# Файл был изменен со времени последней проверки.
fi
fi
let "n+=1"
done <"$dbfile" # Чтение контрольных сумм из файла.
}
# =================================================== #
# main ()
if [ - z "$1" ]
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |


