Искусство программирования на языке сценариев командной оболочки - Мендель Купер
Шрифт:
Интервал:
Закладка:
Вывод от 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 '377n' 'n377'
| 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 Dec 17 2000 employment.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 Dec 17 2000 employment.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'.