- Установка патчей в Linux – работа с утилитой patch
- Что такое патч?
- Синтаксис и основные опции команды patch
- Применение патчей к отдельным файлам
- Работа с проектами
- Linux patch как пользоваться
- 15.1 Применение изменений к другим каталогам
- 15.2 Имена резервных файлов.
- 15.3 Имена файлов отвергнутых изменений
- 15.4 Опции patch
Установка патчей в 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.
Источник
Linux patch как пользоваться
Как правило, patch вызывается следующим образом:
Вы можете указать один или более исходных файлов как аргументы ORIG; каждый из них и опции, управляющие его обработкой, отделяются друг от друга символом ‘+’.
Если вы не указываете входной файл в командной строке, patch пытается пропустить вводный текст, который мог быть добавлен перед началом выдачи diff, и определить имя файла для редактирования. В заголовках контекстного или унифицированного формата diff, patch пытается найти строки, начинающиеся с ‘***’, ‘—‘ или ‘+++’, а среди них выбирает кратчайшее имя существующего файла. В случае неудачи, если есть строка «Index:» во вводном тексте, patch пытается использовать имя файла из этой строки. Если patch не может найти таким образом имя существующего файла из вводного текста, он запрашивает имя файла для модификации у пользователя.
Если входной файл не существует, или доступ к файлу разрешен только для чтения, и существуют соответствующие RCS- или SCCS- файлы, patch пытается извлечь файлы оттуда перед обработкой.
По умолчанию, patch заменяет содержимое исходного входного файла на исправленную версию, создав предварительно резервную копию исходного входного файла. Вы можете также явно указать, куда должен быть помещен выходной файл с помощью опций -o OUTPUT-FILE или —output=OUTPUT-FILE.
15.1 Применение изменений к другим каталогам
Опция patch ‘-d DIRECTORY’ или ‘—directory=DIRECTORY’, делает каталог DIRECTORY текущим каталогом для интерпретации имен файлов, встречающихся в файле изменений, и имен файлом, заданных как аргументы в других опциях (таких как ‘-B’ и ‘-o’). Например, находясь в программе чтения новостей, Вы можете исправить файл в каталоге /usr/src/emacs, применив изменения, присланные в статье телеконференции, непосредственно следующим образом:
patch ищет каждый файл (после всех обрезанных имен каталогов) от текущего каталога, или если Вы указали опцию ‘-d DIRECTORY’, то от указанного в ней каталога.
Например, допустим в файле изменений указано имя файла ‘/gnu/src/emacs/etc/NEWS’. Если используется опция -p или -p0, то это имя файла остается неизмененным. -p1 приводит к рассмотрению имени ‘gnu/src/emacs/etc/NEWS’ (первый символ ‘/’ удаляется). ‘-p4’ приводит к имени ‘etc/NEWS’. Если опция -p не указана вообще, то рассматривается файл с именем ‘NEWS’.
15.2 Имена резервных файлов.
По умолчанию, ‘patch’ делает резервную копию изменяемого файла, переименовывая исходный файл добавляя к его имени расширение ‘.orig’, или ‘
‘ на системах, которые не поддерживают длинных имен файлов. Опции ‘-b BACKUP-SUFFIX’ или ‘—suffix=BACKUP-SUFFIX’ позволяют использовать BACKUP-SUFFIX как расширение для имени резервного файла.
Вы можете так же указать расширение для резервных файлов с помощью переменной окружения ‘SIMPLE_BACKUP_SUFFIX’, действие которой тоже перекрывается этими опциями.
‘patch’ может создавать пронумерованные резервные файлы таким же образом, как это делает GNU Emacs. В этом случае patch будет создавать новый резервный файл каждый раз, когда к исходному файлу применяется patch. Например, если исходный файл называется sink, то резервные копии этого файла будут названы последовательно sink.
Аргумент опций ‘-V BACKUP-STYLE’ или ‘—version-control=BACKUP-STYLE’ определяет способ именования резервных копий. Вы можете так же управлять типом создаваемых резервных копий с помощью переменной окружения ‘VERSION_CONTROL’, действие которой может быть перекрыто при использовании опции ‘-V’. Значения переменной ‘VERSION_CONTROL’ и аргумента опции ‘-V’ такие же, как и для переменной version-control в редакторе GNU Emacs. Кроме того, распознаются более понятные синонимы этих значений. Допустимые значения перечислены ниже; можно указывать однозначно определяемые сокращения. `t’ или `numbered’
Всегда делать пронумерованные резервные копии.
`nil’ или `existing’
Делать нумерованные резервные копии для файлов, для котороых уже имеются резервные копии и простые копии для остальных. Это значение принимается по умолчанию.
`never’ или `simple’
Всегда делать простую резервную копию. Кроме этого, можно указать patch, чтобы он добавлял префикс (например, имя каталога) к имени файла с резервной копией. Опции ‘-B BACKUP-PREFIX’ или ‘—prefix=BACKUP-PREFIX’ позволяют добавить BACKUP-PREFIX перед именем файла. Если используется эта опция, то patch будет игнорировать заданное Вами значение опции ‘-b’.
Если резервная копия уже существует, patch создает новую резервную копию, изменяя первую встретившуюся в имени маленькую букву на соответствующую большую букву. Если больших букв нет в имени, то удалятся первый символ из имени. Это повторяется до тех пор, пока не будет получено имя файла, которой еще не существует.
Если Вы указываете имя выходного файла с помощью опции ‘-o’, то создается резервная копия файла, указанного как ее аргумент, а не входного файла.
15.3 Имена файлов отвергнутых изменений
Имена файлов отвергнутых изменений (файлы, содержащие те изменения, которые patch не смог применить, поскольку не нашел соответствующего места) по умолчанию строятся приписыванием суффикса ‘.rej’ (или ‘#’ — для систем, не поддерживающих длинные имена файлов).
Вы можете явно указать patch, что он должен помещать все отвергнутые изменения в один файл. Опция ‘-r REJECT-FILE’ или ‘—reject-file=REJECT-FILE’ позволяет использовать REJECT-FILE как имя для файла отвергнутых изменений.
15.4 Опции patch
В этом разделе приводится полный список опций, которые понимаются программой ‘patch’. Старые версии ‘patch’ не воспринимают опции с длинными именами и опции ‘-t’, ‘-E’ и ‘-V’.
Несколько однобуквенных опций без аргументов могут быть объединены в один аргумент командной строки (записывается один символ ‘-‘, за которым следуют буквы, соответствующие этим опциям). Квадратные скобки ([ и ]) показывают что опция может иметь необязательный аргумент. `-b BACKUP-SUFFIX’
Использовать BACKUP-SUFFIX как расширение для имен файлов с резервными копиями вместо ‘.orig’ или ‘
Использовать BACKUP-PREFIX как префикс для имени файла с резервной копией. Если эта опция указано, то опция ‘-b’ игнорируется.
Не задавать никаких вопросов (пакетный режим работы).
Рассматривать файл изменений как выдачу diff в контекстном формате.
`-d DIRECTORY’ или `—directory=DIRECTORY’
Каталог DIRECTORY рассматривается как текущий каталог для интерпретации имен файлов, заданных в пакетном файле и в качестве аргументов для других опций.
Выполняет слияние в формате if-then-else. NAME — имя переменной.
Установка внутренних отладочных флагов. Опция представляет интерес только для тех, кто сам патчит (модифицирует) patch.
Файл изменений интерпретируется как скрипт для ed.
Удалять выходные файлы, которые оказались пустыми в результате применения изменений.
Считать, что пользователь уверен в своих действиях, и не задавать никаких вопросов.
Установить значение показателя максимальной неточности в LINES.
Считать, что пользователь уверен в своих действиях, и не задавать никаких вопросов.
Игнорировать изменения, которые patch считает реверсивными или уже примененными. См. также ‘-R’
Установить значение показателя максимальной неточности в LINES.
Печать справочной информации об опциях, воспринимаемых программой patch.
Выполняет слияние в формате if-then-else. NAME — имя переменной.
`—ignore-white-space’ или `-l’
Любая последовательность символов-разделителей в файле изменений считается совпадающей с любой последовательностью символов-разделителей во входном файле.
Файл изменений рассматривается как результат работы diff в нормальном формате.
Игнорировать изменения, которые patch считает реверсивными или уже примененными. См. также ‘-R’
`-o OUTPUT-FILE’ или `—output=OUTPUT-FILE’
OUTPUT-FILE используется как имя выходного файла.
Устанавливает количество отсекаемых имен каталогов в NUMBER.
Использовать BACKUP-PREFIX как префикс для имени файла с резервной копией. Если эта опция указано, то опция ‘-b’ игнорируется.
Работать без выдачи любых сообщений до момента возникновения ошибки.
Использовать REJECT-FILE как имя файла отвергнутых изменений.
Считать, что при создании файла различий имена старого и нового файлов были указаны наоборот (реверсивное изменение).
Использовать REJECT-FILE как имя файла отвергнутых изменений.
Удалять выходные файлы, которые оказались пустыми в результате применения изменений.
Считать, что при создании файла различий имена старого и нового файлов были указаны наоборот (реверсивное изменение).
Работать без выдачи любых сообщений до момента возникновения ошибки.
Пропустить данное изменение из файла изменений, но продолжать обработку со следующего изменения в файле.
Работать без выдачи любых сообщений до момента возникновения ошибки.
Пропустить данное изменение из файла изменений, но продолжать обработку со следующего изменения в файле.
Устанавливает количество отсекаемых имен каталогов в NUMBER.
Использовать BACKUP-SUFFIX как расширение для имен файлов с резервными копиями вместо ‘.orig’ или ‘
Не задавать никаких вопросов.
Рассматривать файл изменений как результат работы diff в унифицированном формате.
Вывести номер версии patch.
Выбрать способ создания резервных копий изменяемых файлов.
Вывести номер версии patch.
Выбрать способ создания резервных копий изменяемых файлов.
Установка внутренних отладочных флагов. Опция представляет интерес только для тех, кто сам патчит (модифицирует) patch. Next Previous Contents
Источник