Настройки шрифта

| |

Фон

| | | |

 

# Почему?

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 -- подавление вывода в колонку 1

 -2 -- подавление вывода в колонку 2

 -3 -- подавление вывода в колонку 3

 -12 -- подавление вывода в колонки 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

1670054224 804083 /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\" ]

then

directory=\"$PWD\" # Если каталог не задан,

else #+ то используется текущий каталог.

directory=\"$1\"

fi



clear # Очистка экрана.



# ------------------------------------------------------------------ #

if [ ! -r \"$dbfile\" ] # Необходимо создать файл с контрольными суммами?

then

echo \"Создание файла с контрольными суммами, \\\"\"$directory\"/\"$dbfile\"\\\".\"; echo

set_up_database

fi

# ------------------------------------------------------------------ #



check_database # Выполнить проверку.



echo



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

#+ это особенно полезно при проверке большого количества файлов.



# Более строгая проверка целостности файлов,

#+ может быть выполнена с помощью пакета \"Tripwire\",

#+ http://sourceforge.net/projects/tripwire/.



exit 0

Более творческий подход к использованию md5sum вы нйдете в Пример A-21.

shred

Надежное, с точки зрения безопасности, стирание файла, посредством предварительной, многократной записи в файл случайной информации, перед тем как удалить его. Эта команда имеет тот же эффект, что и Пример 12-42, но делает это более изящным и безопасным способом.

Является составной частью пакета GNU fileutils.

Имеется ряд технологий, с помощью которых все-таки возможно восстановить файлы, удаленные утилитой shred.

Кодирование и шифрование

uuencode

Эта утилита используется для кодирования двоичных файлов в символы ASCII, после такого кодирования файлы могут, с достаточной степенью безопасности, передаваться по сети, вкладываться в электронные письма и т.п..

uudecode

Утилита декодирования файлов, прошедших обработку утилитой uuencode.

Пример 12-30. Декодирование файлов

#!/bin/bash



lines=35 # 35 строк для заголовка (более чем достаточно).



for File in * # Обход всех файлов в текущем каталоге...

do

search1=`head -$lines $File | grep begin | wc -w`

search2=`tail -$lines $File | grep end | wc -w`

# Закодированные файлы начинаются со слова \"begin\",

#+ и заканчиваются словом \"end\".

if [ \"$search1\" -gt 0 ]

then

if [ \"$search2\" -gt 0 ]

then

echo \"декодируется файл - $File -\"

uudecode $File

fi

fi

done