Самый элегантный способ добавления ppa через скрипт [закрыто]

Я пишу сценарий на bash, который автоматически добавляет PPA. Проблема в том, что если просто выполнить команду add-apt-repository ppa, то после нескольких запусков одного и того же скрипта вы получите кучу дублирующихся закомментированных строк в каждом файле списка PPA в папке /etc/apt/sources.list.d.

Одним из решений этой проблемы является проверка перед добавлением, как описано в этом вопросе/ответе.

Меня немного отталкивает большой блок кода в этом ответе. Что если мы сначала позволим им быть добавленными, а затем очистим файлы? Это выглядело бы так:

sudo apt-add-repository -y ppa:rael-gc/rvm

# remove the duplicate ppa in the files
ls /etc/apt/sources.list.d/*.list |  xargs -n 1 -I {} sh -c "uniq {} | sudo tee {}"

Есть ли отрицательные стороны у вышеупомянутого подхода? Какие-нибудь возможно опасные проблемы?


Пример того, как apt-add-repository делает это:

cat /etc/apt/sources.list.d/rael-gc-ubuntu-rvm-xenial.list
deb http://ppa.launchpad.net/rael-gc/rvm/ubuntu xenial main
# deb-src http://ppa.launchpad.net/rael-gc/rvm/ubuntu xenial main

sudo apt-add-repository -y ppa:rael-gc/rvm

cat /etc/apt/sources.list.d/rael-gc-ubuntu-rvm-xenial.list
deb http://ppa.launchpad.net/rael-gc/rvm/ubuntu xenial main
# deb-src http://ppa.launchpad.net/rael-gc/rvm/ubuntu xenial main
# deb-src http://ppa.launchpad.net/rael-gc/rvm/ubuntu xenial main
2
задан 13 April 2017 в 15:24

1 ответ

Это не точно Обзор Кода, но здесь мы идем.

Не анализируйте вывод ls!

ls /etc/apt/sources.list.d/*.list | xargs ...

Не делайте этого. См. ссылку в заголовке раздела для объяснения почему и возможные альтернативы. Самое легкое и самое изящное решение здесь состояло бы в том, чтобы использовать оболочку globbing для генерации объектов для итерации в для цикла:

for l in /etc/apt/sources.list.d/*.list; do
    uniq "$l" | sudo tee "$l"
done

Преобразование оперативных файлов

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

uniq "$l" | sudo sponge "$l"

или возможно

sudo sed -i ... "$l"

если можно найти, что соответствующий sed сценарий делает задание.

Оба обладают дополнительным преимуществом, что они также не пишут вход в стандартный вывод, но можно подавить это с >/dev/null так или иначе.

Делает uniq действительно найдите дублирующиеся исходные строки Кв.?

Взгляд на sources.list(5), Исходные строки Кв. могут содержать несколько “компонентов”. Следующие исходные файлы эквивалентны, но не идентичны:

  • единственная, многокомпонентная строка:

    deb http://de.archive.ubuntu.com/ubuntu/ trusty-security main restricted
    
  • несколько однокомпонентных строк:

    deb http://de.archive.ubuntu.com/ubuntu/ trusty-security main
    deb http://de.archive.ubuntu.com/ubuntu/ trusty-security restricted
    

Это должно быть очевидно это поэтому uniq не может найти все дублирующиеся исходные строки Кв. Однако начиная с репозиториев на ppa.launchpad.net не поддерживайте несколько компонентов, можно прожить, если Вы только используете PPAs от того сайта. Кроме того, дубликаты могут быть распространены по нескольким файлам, который повреждает этот подход полностью, если Вы не полагаетесь на факт это add-apt-repository управляет исходными файлами несколько разумно и помещает точно один PPA в каждый файл.

В то время как возможно записать программу Bash, которая принимает многокомпонентные строки во внимание при проверке на дубликаты, было бы лучше пользоваться существующими библиотеками программного обеспечения для парсинга исходных строк Кв. вместо того, чтобы прокрутить собственное решение. Одна такая библиотека aptsources модуль Python (упакованный в python-apt или python3-apt). Можно найти пример его использования в apt-remove-duplicate-source-entries (происходящий из вопроса, Как может я автоматически фиксировать W: Целевые Пакеты … настроены многократно?).

1
ответ дан 2 December 2019 в 04:54

Другие вопросы по тегам:

Похожие вопросы: