- HowTo Apply a Patch File To My Linux / UNIX Source Code
- patch command syntax
- How do I create a patch?
- Example: Creating and applying the patch for hello.c sample program on a Linux or Unix like system
- A note about working on an entire source tree
- Установка патчей в Linux – работа с утилитой patch
- Что такое патч?
- Синтаксис и основные опции команды patch
- Применение патчей к отдельным файлам
- Работа с проектами
HowTo Apply a Patch File To My Linux / UNIX Source Code
I am a new Linux and Unix system user. I also know that I can patch binary package using up2date or yum command in Linux. I was wondering is if there’s a way to apply a patch file to downloaded source code on a Linux / UNIX like operating system source tree?
Linux and UNIX source software often comes with security and other patches. You can download them from Internet or project home page. There is a command called patch that apply a diff file or patch to an original source tree.
[donotprint]
Tutorial details | |
---|---|
Difficulty level | Easy |
Root privileges | No |
Requirements | patch and diff commands |
Est. reading time | 5m |
[/donotprint]
The patch command takes a patch file patchfile containing a difference listing produced by the diff program and applies those differences to one or more original files, producing patched versions. Normally the patched versions are put in place of the originals.
patch command syntax
The basic syntax is as follows:
$ patch
To apply a patch, one could run the following command in a shell:
$ patch
In this example, patch foo.c with patch.diff file:
$ patch foo.c
Patches can be undone, or reversed, with the ‘-R’ option:
$ patch -R
How do I create a patch?
To create a patch, one could run the following diff command:
$ diff -u oldfile-name-here newfile-name-here > patch.diff
Example: Creating and applying the patch for hello.c sample program on a Linux or Unix like system
Create a hello.c as follows:
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
Make a copy of the hello.c (or file you wish to modify); both files must be in the same directory, though it may be any directory using cp command:
$ cp hello.c hello-new.c
Edit the file hello-new.c to make it as you want it. In this example, I am fixing a few compiler warning by adding return value from main():
Next, use command diff to create a unified diff patch file called hello.patch:
$ diff -u hello.c hello-new.c > hello.patch
To see patch use cat command as follows:
$ cat hello.patch
Sample outputs:
To apply the patch from hello.patch, enter:
Finally, here is my updated and patched hello.c:
$ cat hello.c
Sample outputs:
You can now compile program:
$ cc hello.c -o hello
Run it as follows:
$ ./hello
Sample outputs:
A note about working on an entire source tree
First, make a copy of the source tree:
## Original source code is in lighttpd-1.4.35/ directory ##
$ cp -R lighttpd-1.4.35/ lighttpd-1.4.35-new/
Cd to lighttpd-1.4.35-new directory and make changes as per your requirements:
$ cd lighttpd-1.4.35-new/
$ vi geoip-mod.c
$ vi Makefile
Finally, create a patch with the following command:
$ cd ..
$ diff -rupN lighttpd-1.4.35/ lighttpd-1.4.35-new/ > my.patch
You can use my.patch file to patch lighttpd-1.4.35 source code on a different computer/server using patch command as discussed above:
patch -p1
See the man page of patch and other command for more information and usage — bash(1)
🐧 Get the latest tutorials on Linux, Open Source & DevOps via
Category | List of Unix and Linux commands |
---|---|
Documentation | help • mandb • man • pinfo |
Disk space analyzers | df • duf • ncdu • pydf |
File Management | cat • cp • less • mkdir • more • tree |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Linux Desktop Apps | Skype • Spotify • VLC 3 |
Modern utilities | bat • exa |
Network Utilities | NetHogs • dig • host • ip • nmap |
OpenVPN | CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04 |
Package Manager | apk • apt |
Processes Management | bg • chroot • cron • disown • fg • glances • gtop • jobs • killall • kill • pidof • pstree • pwdx • time • vtop |
Searching | ag • grep • whereis • which |
Shell builtins | compgen • echo • printf |
Text processing | cut • rev |
User Information | groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w |
WireGuard VPN | Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04 |
Comments on this entry are closed.
Linux and UNIX source software often comes with security and other patches. You can download them from Internet or project home page. There is a command called patch that apply a diff file or patch to an original source tree.
patch takes a patch file patchfile containing a difference listing produced by the diff program and applies those differences to one or more original files, producing patched versions.
guess what I need is a link to the .patch file syntax so I know what it means and can apply the changes manually (unless there’s some other way to do it).
Hi
I want to merge two patch file into one then how I can get that done without any complications and breaking the source.If I apply both separately then it fails.
I have yet to see Wine Internet Explorer , wine-1.3.6 I can click on the white loading bar while new Adobe FlashPlayer 11beta for Internet Explorer (only) is trying to load it in my terminal thru (Wine Windows Program Loader) and Wine Internet Explorer will power-up, but its missing a few stuff. Adobe FP 11b not right one for it (because the accept license agreement tab not there) and wish someone could find right FP, maybe you or someday adobe will produce one? Check-it out and you will see! But the new Adobe Air 11b (IE only) loaded great.
Just For Information:
-p0 in patch command –> entire file name
-p1 in patch command –> file name preceding first forward slash
-p2 in patch command –> file name preceding second forward slash
etc.
Example:
-p0 = /path/to/patch/file
-p1 = path/to/patch/file
-p2 = to/patch/file
-p3 = patch/file
-p4 = file
Spent some time scratching my head over what -p0, -p1 is supposed to mean, and working out how to make patch Rob B Apr 29, 2014 @ 11:43
Thanks for this. It is helpful.
Great document for beginner. Thanks for sharing.
Thanks a lot
very useful article
Can I somehow keep the original file and save the patched file somewhere else?
Aziz, see the -b and -o options of the patch documentation (patch –help)
Источник
Установка патчей в Linux – работа с утилитой patch
Практически каждый разработчик программного обеспечения (ПО), программист или верстальщик сталкивается (и довольно часто) с необходимостью модификации некоторой части рабочего проекта или даже нескольких строк кода. Особенно это актуально, когда в разработке участвует несколько человек, которые могут вносить правки в разных частях проекта. Для удобства и автоматизации действий по составлению таких правок используются специализированные утилиты. Одной из таких является утилита patch и о ней более подробно будет рассказано в данной статье.
Что такое патч?
Говоря о патчах вкупе с утилитой patch, следует подразумевать, что это касается исключительно текстовых данных. Другими словами, происходит работа с исходными кодами проекта, будь то код C++, PHP, HTML и т. д. Вообще, все самые «суровые» программисты или разработчики в процессе своей совместной работы над проектом обмениваются исключительно отдельными правками, а не пересылают друг другу актуальные версии проектов целиком.
Сама правка, т. е. текстовые изменения в исходном коде проектов (для одного его файла или сразу для нескольких) и есть патч или «заплатка». Патч, помимо самих изменений кода содержит также и некоторую служебную информацию, необходимую для правильного «наложения заплатки», т. е. для установки патча. Таким образом, патч — это текстовый файл определённого формата, содержащий в себе данные и инструкции для приведения конечного файла (или проекта) к нужному или актуальному виду.
Утилита patch умеет быстро и эффективно распоряжаться данными из файла-патча, используя для этого хранящиеся в нём инструкции. И таким образом выполняет все рутинные действия по редактированию. Пользователю (разработчику) необходимо лишь правильно выполнить соответствующую команду, задав все необходимые аргументы и опции.
Синтаксис и основные опции команды patch
Нет ничего удивительного в том, что утилита patch относится к категории ПО, которое обязательно должно быть установлено на любой машине для разработки программ, да и вообще для ведения разработки. Практически любой дистрибутив Linux предоставляет утилиту patch предустановленной по-умолчанию.
Стоит также отметить, что по своей функциональности, patch довольно сложна и обладает, без преувеличения, просто огромным набором опций. По этой причине в данной статье будут приведены только самые распространённые приёмы при работе с этой утилитой и только сопутствующие им опции команд. Синтаксис команды patch следующий:
Здесь originalfile – это файл, который необходимо «пропатчить» до актуального состояния. А patchfile – файл-патч. Сразу возникает вопрос: а откуда берётся этот файл-патч? Ответ: он генерируется другой утилитой — diff, которая находит построчные различия между файлами. Либо же патч может быть составлен вручную, автором, если он знаком с соответствующим форматом. Но это бывает крайне редко, обычно прибегают к помощи diff или её аналогов.
В следующей таблице приведены опции команды patch, которые используются наиболее часто:
Опция | Значение |
-i patchfile | Читает информацию из патч-файла, указываемого параметром patchfile. |
-r rejectfile, —reject-file=rejectfile | |
-N, —forward | Когда патч не применяется, то утилита patch обычно пытается определить, выглядит ли ситуация так, как если бы патч уже был применён. Опция -N отключает такое поведение. |
-pnum, strip=num | Обрезает части пути к файлу, разделяемые символом косой черты до уровня, указанного в параметре num. Например: p0 оставит путь /u/john/src/blurfl/blurfl.cpp неизменным, а p4 обрежет тот же путь до blurfl/blurfl.cpp. |
-o outputfile, —output=outputfile | Отправляет вывод в указываемый в параметре outputfile файл. Не следует использовать эту опцию, если в качестве outputfile указывается файл, который должен быть пропатчен. Если в качестве outputfile указать символ дефиса «-», то вывод будет направляться в стандартный поток STD_OUT. |
-E, —remove-empty-file | Удаляет файлы, оказавшиеся пустыми после применения патча. Эта опция имеет смысл, когда используемые патчи имеют не контекстный формат. |
—dry-run | Печатает результаты применения патча без реальной модификации файлов. Полезно для быстрого и безопасного тестирования патчей. |
-R, —reverse | Откатывает все изменения (если они возможны), т. е. отменяет установку патча. |
-c, —context | Интерпретирует файл патча как обычный контекстный формат, генерируемый утилитой diff. |
-b, —backup | Создаёт резервную копию оригинального файла вместо его удаления. |
Применение патчей к отдельным файлам
Прежде, чем начать рассмотрение практических примеров, необходимо сказать несколько слов о той самой утилите, которая и создаёт патчи — diff. Она может генерировать патчи трёх типов — простой, контекстный и контекстный унифицированный. Простой гораздо более компактный по размеру, чем контекстные, но последние гораздо более удобочитаемы и понятны для восприятия пользователем. Для того, чтобы сгенерировать простой патч, для команды diff никаких специальных опций не требуется. А для генерации контекстного или унифицированного контекстного патчей предназначены опции -с и -u соответственно:
Пусть имеется файл с кодом C++ ChildClass.cpp:
И пусть в этот файл было внесено следующее изменение: метод valueSqr() был переименован в calcSqr(). Тогда контекстный патч (файл contextpatch) будет выглядеть следующим образом:
Теперь, чтобы пропатчить старую версию ChildClass.cpp, нужно выполнить команду:
В результате будет получен файл ChildClass_new.cpp с актуальным содержимым.
Работа с проектами
С помощью утилиты patch можно также применять патчи для нескольких файлов, причём расположенных в разных каталогах. Это удобно, когда изменения проводятся в масштабах целого проекта. Но в этом случае и сам патч должен быть особым образом подготовлен утилитой diff.
Пусть имеется старый проект в каталоге base-project. Внутри него имеются подкаталоги include и src, в которых, в свою очередь находятся файлы с изменениями — ChildClass.h (в каталоге include) и ChildClass.cpp (в каталоге src). Сам изменённый (актуальный) проект был помещён в отдельный каталог new-project. Подготовка патча будет выглядеть следующим образом:
Сгенерированный файл-патч project-patch:
Следует обратить внимание, что в данных примерах указываются относительные пути. Файл-патч будет помещён в текущий активный каталог.
Чтобы применить патч нужно выполнить следующую команду:
Как видно, вместо ключа -i можно использовать символ «
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Источник