Как применить патч к файлу (и создать патчи) в Linux

Команда Linux patchпозволяет быстро и безопасно переносить изменения из одного набора файлов в другой набор файлов. Узнайте, как пользоваться patchпростым способом.

Команды patch и diff

Представьте, что у вас на компьютере есть текстовый файл. Вы получаете измененную версию этого текстового файла от кого-то другого. Как быстро перенести все изменения из измененного файла в исходный файл? Вот где patchи diffвступят в игру. patchи diffвстречаются в Linux и других Unix-подобных операционных системах, таких как macOS.

Команда diffпроверяет две разные версии файла и перечисляет различия между ними. Различия могут быть сохранены в файле, который называется файлом исправления.

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

Теперь представьте, что этот процесс происходит со всем каталогом текстовых файлов. Все за один раз. Это сила patch.

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

Что вы делаете с файлом патча, чтобы исправить ваши файлы? Помимо того, что это почти скороговорка, это еще и хороший вопрос. Мы расскажем вам об этом в этой статье.

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

СВЯЗАННЫЕ: Как сравнить два текстовых файла в терминале Linux

Наш пример сценария

В этом сценарии мы находимся в каталоге с именем work, который содержит два других каталога. Один называется рабочим, а другой последним . Рабочий каталог содержит набор файлов исходного кода. В последнем каталоге хранится самая последняя версия этих файлов исходного кода, некоторые из которых были изменены.

На всякий случай рабочий каталог является копией текущей версии текстовых файлов. Это не единственная их копия.

Поиск различий между двумя версиями файла

Команда diffнаходит различия между двумя файлами. Его действие по умолчанию - выводить список измененных строк в окне терминала.

Один файл называется slang.c. Мы сравним версию в рабочем каталоге с версией в последнем каталоге.

Параметр -u (унифицированный) указывает diffтакже перечислить некоторые из неизмененных текстовых строк до и после каждого из измененных разделов. Эти строки называются контекстными линиями. Они помогают  patch команде точно определить, где в исходном файле нужно сделать изменение.

Мы предоставляем имена файлов, чтобы diffзнать, какие файлы сравнивать. Первым отображается исходный файл, затем измененный файл. Это команда, которую мы даем diff:

diff -u рабочий / slang.c последний / slang.c

diffвыводит список, показывающий различия между файлами. Если бы файлы были идентичными, вывода не было бы вообще. Этот тип вывода diffподтверждает, что существуют различия между двумя версиями файлов и что исходный файл требует исправления.

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

Чтобы зафиксировать эти различия в файле исправления, используйте следующую команду. Это та же команда, что и выше, с diffперенаправлением вывода в файл с именем slang.patch.

diff -u рабочий / slang.c latest / slang.c> slang.patch

Имя файла патча произвольное. Вы можете называть это как угодно. Хорошая идея - дать ему расширение «.patch»; однако, поскольку он дает понять, какой это тип файла.

Чтобы  patchвоздействовать на файл исправления и изменить файл working / slang.c, используйте следующую команду. Параметр -u(унифицированный) сообщает patch , что файл исправления содержит унифицированные строки контекста. Другими словами, мы использовали опцию -u с diff, поэтому мы используем -uопцию с patch.

патч -u working.slang.c -i slang.patch

Если все пойдет хорошо, будет одна строка вывода, сообщающая, что вы patchисправляете файл.

Создание резервной копии исходного файла

Мы можем дать указание patchсделать резервную копию исправленных файлов перед их изменением, используя параметр  -b(резервное копирование). Параметр -i(input) сообщает patch имя файла исправления, который следует использовать:

 патч -u -b working.slang.c -i сленг.patch 

Файл исправлен, как и раньше, без видимой разницы в выводе. Однако, если вы посмотрите в рабочую папку, вы увидите, что файл с именем slang.c.orig был создан. Отметки даты и времени файлов показывают, что slang.c.orig - это исходный файл, а slang.c - новый файл, созданный patch.

Использование diff с каталогами

Мы можем использовать diffдля создания файла патча, который содержит все различия между файлами в двух каталогах. Затем мы можем использовать этот файл исправления, patchчтобы применить эти различия к файлам в рабочей папке с помощью одной команды.

Параметры, которые мы собираемся использовать, diff- это параметр -u(унифицированный контекст), который мы использовали ранее, параметр -r(рекурсивный) для diffпросмотра любых подкаталогов и параметр -N(новый файл).

-NОпция указывает , diff как обрабатывать файлы в последней директории, которые не находятся в рабочем каталоге. Он заставляет diffпомещать инструкции в файл исправления, чтобы patch создавать файлы, которые присутствуют в последней директории, но отсутствуют в рабочем каталоге.

Вы можете сгруппировать параметры вместе так, чтобы они использовали один дефис ( -).

Обратите внимание, что мы указываем только имена каталогов, мы не говорим diffсмотреть на конкретные файлы:

diff -ruN рабочий / последний /> slang.patch

Заглядывать внутрь файла исправления

Давайте быстро заглянем в файл патча. Мы будем использовать, lessчтобы посмотреть его содержимое.

Вверху файла показаны различия между двумя версиями slang.c.

Прокручивая файл патча дальше вниз, мы видим, что он описывает изменения в другом файле с именем Structs.h. Это подтверждает, что файл исправления определенно содержит различия между разными версиями нескольких файлов.

Посмотрите, прежде чем прыгать

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

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

Если о проблемах не сообщается, мы можем повторить команду без --dry-runопции и уверенно исправить наши файлы.

Параметр -d(каталог) указывает, с patchкаким каталогом работать.

Обратите внимание, что мы не используем параметр -i(input), чтобы указать, patchкакой файл патча содержит инструкции diff. Вместо этого мы перенаправляем файл патча в patchс <.

патч --dry-run -ruN -d working <slang.patch

Из всего каталога diffнашел два файла для патча. Инструкции относительно модификаций этих двух файлов были проверены patch , и о проблемах не сообщалось.

Предполетные проверки в порядке; мы готовы к взлету.

Исправление каталога

Чтобы действительно применить исправления к файлам, мы используем предыдущую команду без --dry-runопции.

патч -ruN -d рабочий <slang.patch

На этот раз каждая строка вывода не начинается с «проверки», каждая строка начинается с «исправления».

И никаких проблем не сообщается. Мы можем скомпилировать наш исходный код, и у нас будет последняя версия программного обеспечения.

Урегулируйте свои разногласия

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