Linux patch как пользоваться

Обновлено: 02.07.2024

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

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

Использование diff для создания простого патча

Наиболее простой пример использования команды diff - получение различий между двумя файлами, оригинальным и обновленным. Можете, например, написать насколько слов обычного текста, сделать какие-нибудь изменения, и сохранить измененния во второй файл. Теперь вы можете сравнить эти эти два файла, используя команду diff:

Конечно, надо заменить originalfile и updatedfile соответствующими именами файлов. В результате должно получиться что-то вроде этого:

Обратите внимание: Чтобы продемонстрировать создание простого патча, я использовал оригинальный файл, содержащий строку "These are a few words.", и измененный файл, содержащий строку "These still are just a few words."
Вы можете создать эти файлы сами, если хотите запустить команду из статьи и получить тот же результат.

1c1 показывает номер строки и то, что с ней надо сделать. Обратите внимание, что может быть сразу несколько строк(например, 12,15, что означает со строки 12 до строки 15). Символ "c" означает, что патч заменит эту строку. Есть еще два других символа: "a" и "d". Они означают "добавить"(add) и "удалить"(delete) соответственно. Таким образом, синтаксис следующий: (номер строки или диапазон строк)(c,a или d)(номер строки или диапазон строк), хотя когда используются "a" или "d", одна из частей (номер строки или диапазон строк) может содержать только номер одной строки.

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

Знак "<" означает, что патч должен удалить символы после этого знака, а знак ">" означает, что символы после этого знака надо добавить. Когда надо заменить строки ("c" между номерами строк), вы увидите оба знака: и "<", и ">". Когда надо добавить строку ("a" между номерами строк), вы увидите только знак ">", а когда надо удалить строку ("d" между номерами строк), вы увидите только знак "<".

Строка "\ No newline at end of file" появилась из-за того, что я не не нажал enter после того как набрал слова. Считается хорошим тоном заканчивать текстовый файл пустой строкой. Некоторым программам она необходима для работы. Поэтому эта строка появилась после работы команды diff. Добавим пустые строки в конец файлов, и получим более короткий вывод команды diff:

Как вы возможно заметили, я не объяснил что означают 3 знака "-". Они означают конец строк, которые надо заменить и начало строк на которые надо заменить. Разделение старых и новых строк. Вы увидите это знак только при замене ("c" между номерами строк).

Опять же не забудьте заменить originalfile и updatedfile на соответствующие имена файлов. Вы наверное знаете, что опция bash ">" работает со всеми командами. Это очень полезное свойство.

Применение простого патча, который мы создали

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

Естественно, и здесь надо изменить имена файлов на необходимые. Если все прошло хорошо, должен получиться файл, идентичный обновленному. Вы можете убедиться в этом, используя команду diff с опцией “-s”:

Замените текст между [ и ] на путь к оригинальному файлу. Например, если обновленный файл, который вы использовали при создании патча находится в родительской директории вышай текущей, то “[/path/to/the/original/updatedfile]” надо заменить на “..” (bash понимает это как родительскую директорию от текущей). И конечно надо изменить имена файлов на верные.

Поздравляю! Если diff сообщила, что файлы идентичные, вы только что успешно создали и применили патч! Однако формат патча, который мы только что использовали не единственный. В следующей главе мы рассмотрим другой формат патча.

Контекстный патч

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

Результат получится следующий:

Как вы видите, здесь включено имя файла. Это значит, что нам не придется набирать его во время применения патча. Далее идет дата и время последнего изменения файла. строка с 15 “*” показывает начало изменений. Они показывают, что надо сделать со следующим блоком текста. Два номера 1 - это номера строк (здесь тоже может быть сразу несколько строк), а “!” означает, что строки надо заменить. Строка с “!” перед тремя “-” должна быть заменена второй строкой с “!”, которая идет после трех “-”(конечно сам ! не будет включен; это синтаксис контекстного формата). Как вы можете видеть, здесь нет знаков “c”, “a” и “d”.Действие, которое нужно сделать, определяется символом в начале строки. “!” означает замену. Другие символы - “+”, “-” и ” ” (пробел). “+” означает добавление, “-” означает удаление, а ” ” означает ничего не делать: патч использует его чтобы убедиться, что он изменяет правильную часть файла.

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

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

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

Наиболее простой способ получить различия между несколькими файлами - это положить их в одну директорию и выполнить команду diff для этой директории целиком. Вы можете просто передать команде diff в качестве параметров имена директорий вместо имен файлов:


Обратите внимание: Если в директория есть поддиректории, то надо использовать опцию "-r".

В результате должно получится что-то вроде этого:

Как вы видите, нормальный формат содержит только имена файлов и изменяемые строки.

Теперь используем контекстный формат:

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

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

Создать патч было легко, но использование директорий ставит следующую проблему: бедут ли патч изменять только соответствующие файлы в текущей директории, или будет использовать соответствующий путь, указанный в файле? Чтобы узнать это, смотрите следующую главу!

Применение патча к нескольким файлам

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


Обратите внимание: мы используем контекстный формат патча, так как это является хорошим тоном.

Теперь надо использовать полученный патч. Скопируйте оригинальную директорию и патч куда-нибудь и примените следующую команду:

Однако возникает ошибка, что невозможно найти файлы для патча. Команда пытается найти файл file1 в текущей директории (по умолчанию патч убирает все пути перед именем файла). И конено файла нет, так как мы пытаемся обновить файлы в директории originaldirectory. Поэтому мы должны заставить патч использовать полный путь. Это делается следующим образом:

Обратите внимание: Вы может подумать, что можно просто переместиться в originaldirectory и запустить патч. Но это не так! Так делать не стоит: если в в патче содержатся поддиректории, то он будет искать их в рабочей директории, и не найдет, или найдет не те. Используйте опцию "-p", чтобы заставить патч искать файлы в поддиректориях.

Опция "-p" говорит патчу сколько слэшей (включая то, что перед ними, обычно директории) нужно вырезать перед именем файла (обратите внимание, что при использовании опции "-p0", патч будет будет искать файлы и в originaldirectory и в updateddirectory).Когда мы устанавливаем 0, это означает что не надо удалять пути, но можно поставить 1, чтобы удалить первый слэш, или 2, чтобы удалить два слэша, и т.д. Это может быть полезно, если если в патче используется структура каталогов, отличная от вашей. Например, если в патче используется следующая структура каталогов:

Вам надо просто посчитать количество слэшей (/ (1) home/ (2) username/ (3) sources/ (4) program/ (5)) и передать это число в опцие "-p". Если вы используете "-p5", то патч будет искать и в originaldirectory/file1 и в updateddirectory/file1. Не забудьте, что патч рассматривает два слэша друг за другом (как в /home/username//sources) как один. Это вызвано тем, что иногда патч скрипты добавляют дополнительный слэш между директориями.

Восстановление оригинального файла из пропатченного

Иногда возникает необходимость восстановить оригинальный файл из пропатченного. Например, если в нем содержится ошибка. Для этого надо использовать опцию "-R":

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

Унифицированный формат

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

Унифицированный формат похож на контекстный, но это не одно и тоже. Патч в унифицированном формате можно создать так:

Результат будет следующий:

Как вы видите, номера строк заключены между "@". Кроме того, есть дополнительный пробел после "+" или "-". Это экономит несколько байт. Другое различие: в унифицированном формате нет специального знака для замены. Он просто удаляет старые строки ("-") и добавляет новые ("+"). Разница между этими действиями заключается в том, что при замене используется один и тот же номер строки, а при удалении и добавлении разные.

Сравнение форматов

Читая про три разных формата, вы вероятно задумались: а какой же выбрать? Вот небольшое сравнение:

Нормальный формат наиболее совместимый. Любые команды похожие на diff/patch должны понять его. Его недостаток - это отсутствие контекста. Контекстный формат широко распространен, но не все команды его понимают. Его преимущество в наличии контекста. Унифицированный формат тоже включает контекст, и при этом более компактем. Но его поддерживает только GNU diff and patch.

Если вы уверены, что патч буду использовать только пользователи с GNU diff/patch, то лучше всего выбрать унифицированный формат, так как он более компактный. В большинстве других случаев лучший выбор - это контекстный формат. Нормальный формат следует использовать если вы уверены, что пользователь будет применять патч командами, не поддерживающими контекстный формат.

Изменение количества контекстных строк

Можно заставить команду diff включать в патч сеньшее количество строк контекста, чем должно быть. В больших патчах это может сильон уменьшить его размер. Однако если уменьшить количество контекстных строк, это может привести в неработоспособности патча. Цитати из справки GNU diff: "Для большинства операций в патче должно быть хотя бы две строки контекста."

Указать количество контестных строк можно несколькими способами:

Если вы хотите использовать контекстный формат, вы можете вы можете совместить эти указания, добавив в опцию "-C".

Предыдущая команда будет использовать контекстный формат с двумя контекстными строками.

Если вы хотит использовать контекстный формат, вы можете вы можете совместить эти указания, добавив в опцию "-U".

Предыдущая команда будет использовать унифицированный формат с двумя контекстными строками.

Если не указывать какой формат вы хотите использовать, то команда будет выглядеть примерно так:

Однако это будет работать только если вы определите формат. Вам необходимо использовать эту опцию или с "-c" или с "u".

Заключительные слова

Несмотря на то, что эта статья описывает множество особенностей работы команд diff и patch, она не может описать все их возможности. Если вы хотите узнать больше об этих командах, вы можете прочитать страницу помощи по этим командам и документацию GNU.

Favorite

Добавить в избранное

Главное меню » Linux » Как запустить команду patch в Linux

Как запустить команду patch в Linux

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

В этой статье показано, как использовать команду «diff» для создания файла исправления, а затем применить его с помощью команды «patch».

Синтаксис:

Синтаксис команды « patch » следующий:

Создание файла патча с помощью «diff»:

Файл исходного кода 1:

Во-первых, для создания файла исправления требуются две разные версии исходного кода. Созданный мной файл исходного кода называется «myfile.c»: s

Файл исходного кода 2:

Теперь скопируйте содержимое myfile.c в new_myfile.c, используя:

Внесите некоторые изменения во вновь созданный файл:

Проверка разницы:

Давайте создадим файл patch с именем myfile.patch:

Вы можете распечатать файл patch, выполнив команду ниже:

Применение файла исправления:

Чтобы применить patch, используйте:

Убедитесь, что файл исправления находится в каталоге, в котором размещен файл исходного кода.

Сделайте резервную копию перед установкой patch:

Используйте параметр «-b» для создания резервной копии файла исправления:

Установка версии файла резервной копии

Если вам нужно несколько резервных копий одного файла резервной копии, используйте параметр «-V». Он устанавливает номер версии каждого файла резервной копии. Выполните команду, указанную ниже:

Проверить файлы исправлений

Если вы хотите проверить или понаблюдать за результатом установки исправлений, используйте опцию «–dry-run». Он не вносит никаких изменений в исходный файл:

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

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

Использование diff для создания простого патча

Наиболее простой пример использования команды diff - получение различий между двумя файлами, оригинальным и обновленным. Можете, например, написать насколько слов обычного текста, сделать какие-нибудь изменения, и сохранить измененния во второй файл. Теперь вы можете сравнить эти эти два файла, используя команду diff:

Конечно, надо заменить originalfile и updatedfile соответствующими именами файлов. В результате должно получиться что-то вроде этого:

Обратите внимание: Что бы продемонстрировать создание простого патча, я использовал оригинальный файл, содержащий строку "These are a few words.", и измененный файл, содержащий строку "These still are just a few words." Вы можете создать эти файлы сами, если хотите запустить команду из статьи и получить тот же результат.

1c1 показывает номер строки и то, что с ней надо сделать. Обратите внимание, что может быть сразу несколько строк(например, 12,15, что означает со строки 12 до строки 15). Символ "c" означает, что патч заменит эту строку. Есть еще два других символа: "a" и "d". Они означают "добавить"(add) и "удалить"(delete) соответственно. Таким образом, синтаксис следующий: (номер строки или диапазон строк)(c,a или d)(номер строки или диапазон строк), хотя когда используются "a" или "d", одна из частей (номер строки или диапазон строк) может содержать только номер одной строки.

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

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

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

Знак "<" означает, что патч должен удалить символы после этого знака, а знак ">" означает, что символы после этого знака надо добавить. Когда надо заменить строки ("c" между номерами строк), вы увидите оба знака: и "<", и ">". Когда надо добавить строку ("a" между номерами строк), вы увидите только знак ">", а когда надо удалить строку ("d" между номерами строк), вы увидите только знак "<".

Строка "\ No newline at end of file" появилась из-за того, что я не не нажал enter после того как набрал слова. Считается хорошим тоном заканчивать текстовый файл пустой строкой. Некоторым программам она необходима для работы. Поэтому эта строка появилась после работы команды diff. Добавим пустые строки в конец файлов, и получим более короткий вывод команды diff:

Как вы возможно заметили, я не объяснил что означают 3 знака "-". Они означают конец строк, которые надо заменить и начало строк на которые надо заменить. Разделение старых и новых строк. Вы увидите это знак только при замене ("c" между номерами строк).

Опять же не забудьте заменить originalfile и updatedfile на соответствующие имена файлов. Вы наверное знаете, что опция bash ">" работает со всеми командами. Это очень полезное свойство.

Применение простого патча, который мы создали

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

Естественно, и здесь надо изменить имена файлов на необходимые. Если все прошло хорошо, должен получиться файл, идентичный обновленному. Вы можете убедиться в этом, используя команду diff с опцией "-s":

Замените текст между [ и ] на путь к оригинальному файлу. Например, если обновленный файл, который вы использовали при создании патча находится в родительской директории вышай текущей, то "[/path/to/the/original/updatedfile]" надо заменить на ".." (bash понимает это как родительскую директорию от текущей). И конечно надо изменить имена файлов на верные.

Поздравляю! Если diff сообщила, что файлы идентичные, вы только что успешно создали и применили патч! Однако формат патча, который мы только что использовали не единственный. В следующей главе мы рассмотрим другой формат патча.

Контекстный патч

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

Результат получится следующий:

Как вы видите, здесь включено имя файла. Это значит, что нам не придется набирать его во время применения патча. Далее идет дата и время последнего изменения файла. строка с 15 "*" показывает начало изменений. Они показывают, что надо сделать со следующим блоком текста. Два номера 1 - это номера строк (здесь тоже может быть сразу несколько строк), а "!" означает, что строки надо заменить. Строка с "!" перед тремя "-" должна быть заменена второй строкой с "!", которая идет после трех "-"(конечно сам ! не будет включен; это синтаксис контекстного формата). Как вы можете видеть, здесь нет знаков "c", "a" и "d".Действие, которое нужно сделать, определяется символом в начале строки. "!" означает замену. Другие символы - "+", "-" и " " (пробел). "+" означает добавление, "-" означает удаление, а " " означает ничего не делать: патч использует его чтобы убедиться, что он изменяет правильную часть файла.

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

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

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

Наиболее простой способ получить различия между несколькими файлами - это положить их в одну директорию и выполнить команду diff для этой директории целиком. Вы можете просто передать команде diff в качестве параметров имена директорий вместо имен файлов:

Обратите внимание: Если в директория есть поддиректории, то надо использовать опцию "-r".

В результате должно получится что-то вроде этого:

Как вы видите, нормальный формат содержит только имена файлов и изменяемые строки.

Теперь используем контекстный формат:

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

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

Создать патч было легко, но использование директорий ставит следующую проблему: бедут ли патч изменять только соответствующие файлы в текущей директории, или будет использовать соответствующий путь, указанный в файле? Чтобы узнать это, смотрите следующую главу!

Применение патча к нескольким файлам

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

Обратите внимание: мы используем контекстный формат патча, так как это является хорошим тоном.

Теперь надо использовать полученный патч. Скопируйте оригинальную директорию и патч куда-нибудь и примените следующую команду:

Однако возникает ошибка, что невозможно найти файлы для патча. Команда пытается найти файл file1 в текущей директории (по умолчанию патч убирает все пути перед именем файла). И конено файла нет, так как мы пытаемся обновить файлы в директории originaldirectory. Поэтому мы должны заставить патч использовать полный путь. Это делается следующим образом:

Обратите внимание: Вы может подумать, что можно просто переместиться в originaldirectory и запустить патч. Но это не так! Так делать не стоит: если в в патче содержатся поддиректории, то он будет искать их в рабочей директории, и не найдет, или найдет не те. Используйте опцию "-p", чтобы заставить патч искать файлы в поддиректориях.

Опция "-p" говорит патчу сколько слэшей (включая то, что перед ними, обычно директории) нужно вырезать перед именем файла (обратите внимание, что при использовании опции "-p0", патч будет будет искать файлы и в originaldirectory и в updateddirectory).Когда мы устанавливаем 0, это означает что не надо удалять пути, но можно поставить 1, чтобы удалить первый слэш, или 2, чтобы удалить два слэша, и т.д. Это может быть полезно, если если в патче используется структура каталогов, отличная от вашей. Например, если в патче используется следующая структура каталогов:

Вам надо просто посчитать количество слэшей (/ (1) home/ (2) username/ (3) sources/ (4) program/ (5)) и передать это число в опцие "-p". Если вы используете "-p5", то патч будет искать и в originaldirectory/file1 и в updateddirectory/file1. Не забудьте, что патч рассматривает два слэша друг за другом (как в /home/username//sources) как один. Это вызвано тем, что иногда патч скрипты добавляют дополнительный слэш между директориями.

Восстановление оригинального файла из пропатченного

Иногда возникает необходимость восстановить оригинальный файл из пропатченного. Например, если в нем содержится ошибка. Для этого надо использовать опцию "-R":

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

Унифицированный формат

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

Унифицированный формат похож на контекстный, но это не одно и тоже. Патч в унифицированном формате можно создать так:

Результат будет седующий:

Как вы видите, номера строк заключены между "@". Кроме того, есть дополнительный пробел после "+" или "-". Это экономит несколько байт. Другое различие: в унифицированном формате нет специального знака для замены. Он просто удаляет старые строки ("-") и добавляет новые ("+"). Разница между этими действиями заключается в том, что при замене используется один и тот же номер строки, а при удалении и добавлении разные.

Сравнение форматов

Читая про три разных формата, вы вероятно задумались: а какой же выбрать? Вот небольшое сравнение:

Нормальный формат наиболее совместимый. Любые команды похожие на diff/patch должны понять его. Его недостаток - это отсутствие контекста.

Контекстный формат широко распространен, но не все команды его понимают. Его преимущество в наличии контекста.

Унифицированный формат тоже включает контекст, и при этом более компактем. Но его поддерживает только GNU diff and patch.

Если вы уверены, что патч буду использовать только пользователи с GNU diff/patch, то лучше всего выбрать унифицированный формат, так как он более компактный. В большинстве других случаев лучший выбор - это контекстный формат. Нормальный формат следует использовать если вы уверены, что пользователь будет применять патч командами, не поддерживающими контекстный формат.

Изменение количества контекстных строк

Можно заставить команду diff включать в патч сеньшее количество строк контекста, чем должно быть. В больших патчах это может сильон уменьшить его размер. Однако если уменьшить количество контекстных строк, это может привести в неработоспособности патча. Цитати из справки GNU diff: "Для большинства операций в патче должно быть хотя бы две строки контекста."

Указать количество контестных строк можно несколькими способами:

Если вы хотит использовать контекстный формат, вы можете вы можете совместить эти указания, добавив в опцию "-C". Пример:

]$ diff -C 2 originaldirectory/ updateddirectory/

Предыдущая команда будет использовать контекстный формат с двумя контекстными строками.

Если вы хотит использовать контекстный формат, вы можете вы можете совместить эти указания, добавив в опцию "-U". Пример:

]$ diff -U 2 originaldirectory/ updateddirectory/

Предыдущая команда будет использовать унифицированный формат с двумя контекстными строками.

Если не указывать какой формат вы хотите использовать, то команда будет выглядеть примерно так:

]$ diff -2 originaldirectory/ updateddirectory/

Заключительные слова

Несмотря на то, что эта статья описывает множество особенностей работы команд diff и patch, она не может описать все их возможности. Если вы хотите узнать больше об этих командах, вы можете прочитать страницу помощи по этим командам и документацию GNU.

Как правило, patch вызывается следующим образом:

Если Вы не указываете PATCHFILE, или если вместо PATCHFILE указан '-', patch читает файл изменений, полученный в результате работы diff, со стандартного ввода.

Вы можете указать один или более исходных файлов как аргументы ORIG; каждый из них и опции, управляющие его обработкой, отделяются друг от друга символом '+'.

Если вы не указываете входной файл в командной строке, patch пытается пропустить вводный текст, который мог быть добавлен перед началом выдачи diff, и определить имя файла для редактирования. В заголовках контекстного или унифицированного формата diff, patch пытается найти строки, начинающиеся с '***', '---' или '+++', а среди них выбирает кратчайшее имя существующего файла. В случае неудачи, если есть строка "Index:" во вводном тексте, patch пытается использовать имя файла из этой строки. Если patch не может найти таким образом имя существующего файла из вводного текста, он запрашивает имя файла для модификации у пользователя.

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

По умолчанию, patch заменяет содержимое исходного входного файла на исправленную версию, создав предварительно резервную копию исходного входного файла. Вы можете также явно указать, куда должен быть помещен выходной файл с помощью опций -o OUTPUT-FILE или --output=OUTPUT-FILE.

15.1 Применение изменений к другим каталогам

Иногда имена файлов, указанные в файле изменений, содержат ведущие имена каталогов, но Вы держите Ваши файлы в каталоге, отличном от того, что указан там. В этих случаях, Вы можете использовать опцию '-p[NUMBER]' или '--strip[=NUMBER]' для установки, какое количество / символов '/' и имен каталогов между ними должно быть отрезано от начала имени файла. '-p' без указания аргумента эквивалентно '-p0'. По умолчанию, patch обрезает все ведущие имена каталогов, оставляя только имя файла, за исключением случая, когда в файле изменений имя файла задано относительно (первый символ имени - не '/'), и все ведущие каталоги существуют. Тогда patch не обрезает ведущие имена каталогов.

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, что он должен помещать все отвергнутые изменения в один файл. Опция '-r REJECT-FILE' или '--reject-file=REJECT-FILE' позволяет использовать REJECT-FILE как имя для файла отвергнутых изменений.

15.4 Опции patch

В этом разделе приводится полный список опций, которые понимаются программой 'patch'. Старые версии 'patch' не воспринимают опции с длинными именами и опции '-t', '-E' и '-V'.

Несколько однобуквенных опций без аргументов могут быть объединены в один аргумент командной строки (записывается один символ '-', за которым следуют буквы, соответствующие этим опциям). Квадратные скобки ([ и ]) показывают что опция может иметь необязательный аргумент. `-b BACKUP-SUFFIX'

Использовать BACKUP-SUFFIX как расширение для имен файлов с резервными копиями вместо '.orig' или '

`-B BACKUP-PREFIX'

Использовать BACKUP-PREFIX как префикс для имени файла с резервной копией. Если эта опция указано, то опция '-b' игнорируется.

Не задавать никаких вопросов (пакетный режим работы).

`-c' или `--context'

Рассматривать файл изменений как выдачу diff в контекстном формате.

`-d DIRECTORY' или `--directory=DIRECTORY'

Каталог DIRECTORY рассматривается как текущий каталог для интерпретации имен файлов, заданных в пакетном файле и в качестве аргументов для других опций.

Выполняет слияние в формате if-then-else. NAME - имя переменной.

`--debug=NUMBER'

Установка внутренних отладочных флагов. Опция представляет интерес только для тех, кто сам патчит (модифицирует) patch.

Файл изменений интерпретируется как скрипт для ed.

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

Считать, что пользователь уверен в своих действиях, и не задавать никаких вопросов.

Установить значение показателя максимальной неточности в LINES.

Считать, что пользователь уверен в своих действиях, и не задавать никаких вопросов.

Игнорировать изменения, которые patch считает реверсивными или уже примененными. См. также '-R'

Установить значение показателя максимальной неточности в LINES.

Печать справочной информации об опциях, воспринимаемых программой patch.

Выполняет слияние в формате if-then-else. NAME - имя переменной.

`--ignore-white-space' или `-l'

Любая последовательность символов-разделителей в файле изменений считается совпадающей с любой последовательностью символов-разделителей во входном файле.

`-n' или `--normal'

Файл изменений рассматривается как результат работы diff в нормальном формате.

Игнорировать изменения, которые patch считает реверсивными или уже примененными. См. также '-R'

`-o OUTPUT-FILE' или `--output=OUTPUT-FILE'

OUTPUT-FILE используется как имя выходного файла.

Устанавливает количество отсекаемых имен каталогов в NUMBER.

`--prefix=BACKUP-PREFIX'

Использовать BACKUP-PREFIX как префикс для имени файла с резервной копией. Если эта опция указано, то опция '-b' игнорируется.

`-r REJECT-FILE'

Использовать REJECT-FILE как имя файла отвергнутых изменений.

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

`--reject-file=REJECT-FILE'

Использовать REJECT-FILE как имя файла отвергнутых изменений.

`--remove-empty-files'

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

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

Пропустить данное изменение из файла изменений, но продолжать обработку со следующего изменения в файле.

Пропустить данное изменение из файла изменений, но продолжать обработку со следующего изменения в файле.

Устанавливает количество отсекаемых имен каталогов в NUMBER.

`--suffix=BACKUP-SUFFIX'

Использовать BACKUP-SUFFIX как расширение для имен файлов с резервными копиями вместо '.orig' или '

Не задавать никаких вопросов.

`-u' или `--unified'

Рассматривать файл изменений как результат работы diff в унифицированном формате.

Вывести номер версии patch.

`-V BACKUP-STYLE'

Выбрать способ создания резервных копий изменяемых файлов.

Вывести номер версии patch.

`--version=control=BACKUP-STYLE'

Выбрать способ создания резервных копий изменяемых файлов.

Установка внутренних отладочных флагов. Опция представляет интерес только для тех, кто сам патчит (модифицирует) patch. Next Previous Contents

Читайте также: