Как создать и применить патч в Linux


Создание патч-файла:

diff -Naur olddir newdir > new-patch
- или -
diff -Naur oldfile newfile >new-patch

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

При создании патч-файла постарайтесь убедиться, что глубина вложенных каталогов одинакова для имени пути старой и новой директории патча. Для примера:
--- old/modules/pcitable	Mon Sep 27 11:03:56 1999
    new/modules/pcitable	Tue Dec 19 20:05:41 2000
Вышеуказанное будет хорошо работать с командой diff как патч.
--- old/try1/other/modules/pcitable	Mon Sep 27 11:03:56 1999
    new/modules/pcitable	Tue Dec 19 20:05:41 2000
Возможны проблемы при формировании патча с помощью команды diff и вышеуказанных строк. Отметьте, что первая имеет 4 уровня вложенных каталогов и вторая всего лишь два. Я бы советовал изменить --- и строки, чтобы в обоих случаях структура каталогов имела одинаковый уровень вложения.

Использование команды Patch:

patch -p0 <new-patch
patch -p1 <new-patch
Какую из приведённых выше команд patch Вам использовать зависит от Вашей текущей рабочей директории.
Другая методика для вызова команды patch - использование стандартного ввода patch:
cat new-patch | patch -p0
Другая методика вызова команды patch - использование "here document":
patch -p0 << EOF
--- old/modules/pcitable	Mon Sep 27 11:03:56 1999
    new/modules/pcitable	Tue Dec 19 20:05:41 2000
@@ -1,4  1,6 @@
 0x0e11	0xae10	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x1000	0x0010	"cpqarray"	"Compaq|Integrated Array Controller"
 0x1011	0x0046	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae32	"tlan"	"Compaq|Netelligent 10/100"
 0x0e11	0xae34	"tlan"	"Compaq|Netelligent 10"
 0x0e11	0xae35	"tlan"	"Compaq|Integrated NetFlex-3/P"
@@ -21,6  23,7 @@
 0x1000	0x000f	"ncr53c8xx"	"Symbios|53c875"
 0x1000	0x0012	"ncr53c8xx"	"Symbios|53c895a"
 0x1000	0x008f	"ncr53c8xx"	"Symbios|53c875J"
 0x1000	0x000a	"sym53c8xx"	"Symbios|53c1510"
 0x1000	0x0701	"yellowfin"	"Symbios|83C885 gigabit ethernet"
 0x1000	0x0702	"yellowfin"	"Symbios|Yellowfin G-NIC gigabit ethernet"
 0x1011	0x0001	"tulip"	"DEC|DECchip 21050"
--- old/usr/share/kudzu/pcitable	Sun Sep 26 17:11:23 1999
    new/usr/share/kudzu/pcitable	Tue Dec 19 20:05:41 2000
@@ -15,6  15,8 @@
 0x0e11	0x3034	"unknown"	"Compaq|QVision 1280/p"
 0x0e11	0x4000	"unknown"	"Compaq|4000 [Triflex]"
 0x0e11	0xa0f3	"ignore"	"Compaq|Triflex PCI to ISA Bridge"
 0x1000	0x0010	"cpqarray"	"Compaq|Integrated Array Controller"
 0x1011	0x0046	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae10	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae29	"unknown"	"Compaq|MIS-L"
 0x0e11	0xae2a	"unknown"	"Compaq|MPC"
@@ -46,6  48,7 @@
 0x1000	0x000f	"ncr53c8xx"	"Symbios|53c875"
 0x1000	0x0012	"ncr53c8xx"	"Symbios|53c895a"
 0x1000	0x008f	"ncr53c8xx"	"Symbios|53c875J"
 0x1000	0x000a	"sym53c8xx"	"Symbios|53c1510"
 0x1000	0x0701	"yellowfin"	"Symbios|83C885 gigabit ethernet"
 0x1000	0x0702	"yellowfin"	"Symbios|Yellowfin G-NIC gigabit ethernet"
 0x1000	0x0901	"unknown"	"Symbios|61C102"
EOF
При использовании "here document", patch прочтёт все следующие строки, пока не достигнет разделителя, который мы задали после << символа. Разделитель, который мы выбрали должен присутствовать в начале строки, и должен быть одиночным. В нашем случае, в качестве разделителя мы используем EOF. EOF не имеет специального значения, кроме факта, что маловероятно, что у нас была бы причина ввести EOF в начале любой данной строки.

Для получения дополнительной информации по данной документации нажмите:
heredoc.html

Уровни в команде Patch (-p0 или -p1?):

Опция -p будет отбрасывать уровни каталогов из патч-файла. Например: если у Вас есть патч-файл с таким заголовком:
--- old/modules/pcitable	Mon Sep 27 11:03:56 1999
    new/modules/pcitable	Tue Dec 19 20:05:41 2000
Использование ключа -p0 будет подразумевать, что от Вашей текущей рабочей директории, требуется найти подкаталог "new", затем "modules" расположенный ниже, затем файл "pcitable" в данном каталоге.

Использование ключа -p1 отбросит 1-ый уровень из пути и будет ожидаться поиск (из Вашей текущей рабочей директории) каталога "modules", затем файла "pcitable". Patch проигнорирует директорию "new" упомянутую в заголовке патч-файла.

Использование ключа -p2 отбросит два первых уровня из пути. Будет ожидаться поиск командой Patch каталога "pcitable" в текущей рабочей директории. Patch проигнорирует каталоги "new" и "modules" упомянутые в заголовке патч-файла.

Использование ключа -p3, в данном примере, будет не лучшей идеей. Patch, скорее всего, ничего не пропатчит.

...

Применение команды Patch:

Перейдите в требуемую директорию и выполните команду patch (смотрите Использование команды Patch выше). Обычно это:
cd /usr/src/linux
patch -p0 <new-patch
если у patchfile нет "linux" как части структуры каталогов в строке, в таком случае выполните команду patch с ключом -p1 следующим образом:
patch -p1 <new-patch

Заголовок патча:

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

Составные патчи в патч-файле:

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

Пример способа просмотра патч-файла:

less /tmp/file-patch <ENTER>
/--- <ENTER>
n
n
n
Отметьте, что "/" вызывает поисковую функцию в команде less, и при каждом нажатии "n" less будет производить поиск следующего соответствия искомой строки.

Куски:

Кусок - это секция, которая будет пропатчена. Кусок обычно начинается и заканчивается строками, которые не нуждаются ни в каких изменениях, они только упоминаются так, чтобы Patch мог найти, соответствующее место в файлах для патча. Кусок в этих примерах начинается с двойного символа at (@@) и оканчивается либо с началом нового куска, либо когда встречается новый заголовок патча. Вот пример куска:
@@ -1,4  1,6 @@
 0x0e11	0xae10	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x1000	0x0010	"cpqarray"	"Compaq|Integrated Array Controller"
 0x1011	0x0046	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae32	"tlan"	"Compaq|Netelligent 10/100"
 0x0e11	0xae34	"tlan"	"Compaq|Netelligent 10"
 0x0e11	0xae35	"tlan"	"Compaq|Integrated NetFlex-3/P"

Отступы в Куске:

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

Первый столбец Куска ( , -, и пробел):

Пробел указывает, что конкретно эта строка будет добавлена.

- указывает, что конкретно эта строка будет удалена.

Строка без плюса или минуса указывает на то, что конкретно эта строка кода является точкой отсчёта.

Пример патч-файла:

diff -u old/modules/pcitable new/modules/pcitable
--- old/modules/pcitable	Mon Sep 27 11:03:56 1999
    new/modules/pcitable	Tue Dec 19 20:05:41 2000
@@ -1,4  1,6 @@
 0x0e11	0xae10	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x1000	0x0010	"cpqarray"	"Compaq|Integrated Array Controller"
 0x1011	0x0046	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae32	"tlan"	"Compaq|Netelligent 10/100"
 0x0e11	0xae34	"tlan"	"Compaq|Netelligent 10"
 0x0e11	0xae35	"tlan"	"Compaq|Integrated NetFlex-3/P"
@@ -21,6  23,7 @@
 0x1000	0x000f	"ncr53c8xx"	"Symbios|53c875"
 0x1000	0x0012	"ncr53c8xx"	"Symbios|53c895a"
 0x1000	0x008f	"ncr53c8xx"	"Symbios|53c875J"
 0x1000	0x000a	"sym53c8xx"	"Symbios|53c1510"
 0x1000	0x0701	"yellowfin"	"Symbios|83C885 gigabit ethernet"
 0x1000	0x0702	"yellowfin"	"Symbios|Yellowfin G-NIC gigabit ethernet"
 0x1011	0x0001	"tulip"	"DEC|DECchip 21050"
--- old/usr/share/kudzu/pcitable	Sun Sep 26 17:11:23 1999
    new/usr/share/kudzu/pcitable	Tue Dec 19 20:05:41 2000
@@ -15,6  15,8 @@
 0x0e11	0x3034	"unknown"	"Compaq|QVision 1280/p"
 0x0e11	0x4000	"unknown"	"Compaq|4000 [Triflex]"
 0x0e11	0xa0f3	"ignore"	"Compaq|Triflex PCI to ISA Bridge"
 0x1000	0x0010	"cpqarray"	"Compaq|Integrated Array Controller"
 0x1011	0x0046	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae10	"cpqarray"	"Compaq|Smart-2/P RAID Controller"
 0x0e11	0xae29	"unknown"	"Compaq|MIS-L"
 0x0e11	0xae2a	"unknown"	"Compaq|MPC"
@@ -46,6  48,7 @@
 0x1000	0x000f	"ncr53c8xx"	"Symbios|53c875"
 0x1000	0x0012	"ncr53c8xx"	"Symbios|53c895a"
 0x1000	0x008f	"ncr53c8xx"	"Symbios|53c875J"
 0x1000	0x000a	"sym53c8xx"	"Symbios|53c1510"
 0x1000	0x0701	"yellowfin"	"Symbios|83C885 gigabit ethernet"
 0x1000	0x0702	"yellowfin"	"Symbios|Yellowfin G-NIC gigabit ethernet"
 0x1000	0x0901	"unknown"	"Symbios|61C102"

Анализ вышеприведённого примера:

Данный пример был создан с использованием следующей команды diff:
diff -u old/modules/pcitable new/modules/pcitable
Однако теперь бы я использовал только опции -Naur вместо -u. Данный пример модифицирует два файла: new/modules/pcitable, и new/usr/share/kudzu/pcitable.

В первом заголовке патча есть два куска. Конкретно эти куски добавляют 2 строки и 1 строку соответственно.


Поиск по сайту в FreeFind!:
Поиск в Google!:

WWW cpqlinux.com

Текущее положение:
Вернуться на главную: www.cpqlinux.com

Автор:
Ричард "Черный" (Richard Black)
Контакты: contact.html


Сайт создан в: 9/20/1999