git filter-branch
запускает /bin/sh /usr/lib/git-core/git-filter-branch
, и этот скрипт оценивает аргумент --index-filter
с помощьюeval
.
Таким образом, этот аргумент оценивается как /bin/sh
код.
В большинстве систем /bin/sh
будет в той или иной степени интерпретатором языка POSIX sh
, хотя в некоторых, таких как Solaris 10 и старше, это все еще может быть древний язык Bourne sh
.
Когда дело доходит до синтаксиса цитирования, это мало что меняет.
В любом случае нельзя использовать ни один из расширенных операторов кавычек ksh/bash/zsh, например $'...'
.Это означает, что вы не можете использовать оператор GNU/bash/zsh/ksh printf %q
илиmksh/bash
${var@Q}
или трассировку xtrace
для создания цитирования, поскольку в некоторых случаях прибегают к $'...'
. Они также используют некоторые формы цитирования, которые -небезопасны для локализации (, например\
).
Один из встроенных операторов цитирования, который вы можете использовать, — это zsh
флаг раскрытия параметра qq
, так как он использует одинарные кавычки:
files=(foo 'a b c' $'a\nb\nc' --foo-- "a'b")
git filter-branch --index-filter "git rm -rf --cached -- ${${(@qq)files}}" HEAD
Чтобы увидеть, как zsh
цитирует эти:
$ printf '<%s>\n' "${${(@qq)files}}"
<'foo' 'a b c' 'a
b
c' '--foo--' 'a'\''b'>
С помощью bash/ksh/yash/zsh вы можете сделать то же самое цитирование, используя такую функцию, как:
shquote() {
LC_ALL=C awk -v q=\' '
BEGIN{
for (i=1; i
А потом:
git filter-branch --index-filter "git rm -rf --cached -- $(shquote "${files[@]}")" HEAD
База данных dpkg (в/var/lib/dpkg/status
)хранит предполагаемое состояние пакета в той же строке, что и текущее состояние, как описано вdpkg(1)
. Таким образом, установленный пакет будет иметь запись, аналогичную этому примеру:
# dpkg -s hello| egrep '^(Package|Status|Architecture):'
Package: hello
Status: install ok installed
Architecture: amd64
После того, как вы используете инструмент для установки намерения удалить его, он будет отображаться как:
# dpkg -s hello| egrep '^(Package|Status|Architecture):'
Package: hello
Status: deinstall ok installed
Architecture: amd64
С purge
вместо deinstall
для пакета -с продувкой -.
Возможно, вы выбрали (для деинсталляции )важного пакета, который инициировал изменение других выбранных пакетов или целой группы пакетов.
Есть несколько инструментов, которые могут это сделать, среди них почтенный dselect
, aptitude
, нижний уровень dpkg --set-selections
илиapt-mark
. Последний проще в использовании, но его все же нельзя использовать для проверки того, что было изменено (, потому что он не сравнивает deinstall
с installed
выше )и может выполнять только одну операцию за раз, поэтому быть очень медленным при нескольких исправлениях. dpkg --set-selections
будет предпочтительнее, потому что он может сделать это за один вызов.
Обратите внимание, что все стало немного сложнее с несколькими арками -, где необходимо получить значение Architecture
, чтобы отличить пакет, установленный дважды в двух архитектурах. Обратите внимание, что архитектура all
также работает для пакетов без реальной архитектуры.
Вот cancel-changes.awk
сценарий, который установит намерение быть совместимым с текущим состоянием :установить то, что установлено, очистить то, что не установлено, и оставить удаленным то, что удалено (с сохранением файлов конфигурации ), в формате, подходящем для dpkg --set-selections
.
#!/usr/bin/awk -f
/^Package:/ { package=$2; newintent="none" }
/^Status: (purge|deinstall) ok installed$/ { newintent="install" }
/^Status: install ok config-files$/ { newintent="deinstall" }
/^Status: install ok not-installed$/ { newintent="purge" }
/^Architecture:/ { package=package ":" $2 }
/^$/ && newintent != "none" { print package, newintent }
Вы должны проверить вывод этого скрипта, прежде чем передать его dpkg --set-selections
. В будущем выпуске Debian (и Ubuntu )внутренний формат может измениться.
Вот пример использования в Debian 10 для тестирования пакета-жертвы hello
.
# apt-get install hello
[...]
# apt-mark remove hello
Selected hello for removal.
# dpkg -l hello
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-==================================
ri hello 2.10-2 amd64 example package based on GNU hello
# cancel-changes.awk < /var/lib/dpkg/status
hello:amd64 install
# cancel-changes.awk < /var/lib/dpkg/status | dpkg --set-selections
# dpkg -l hello
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-==================================
ii hello 2.10-2 amd64 example package based on GNU hello
Хорошо. Я смог обойти это, хотя я не знаю, является ли это реальным решением или просто «пластырем», который скрывает более глубокую, основную проблему. Вот что я сделал...
Прежде всего, я попытался выполнить apt install
один из тех пакетов, которые были помечены для удаления. Это удалось, и я получил список оставшихся 1400+ пакетов с несколькими пакетами в каждой строке вывода.
Я скопировал этот список пакетов в файл и добавил pre -ожидание apt install
в каждой строке, а затем прогнал его через свою оболочку.
Это преобразовало все эти пакеты из «автоматического» в «ручной».
Затем я запустил aptitude keep-all
, и теперь все пакеты перестали отображаться как «неиспользуемые».
Я рад, что смог это сделать, но я все еще не понимаю, как вообще могла возникнуть эта проблема. И, как я уже упоминал, я не знаю, есть ли в моей системе другая, более основная проблема с apt
или aptitude
, которую еще нужно исправить.