pip 10 a apt: jak se vyhnout chybám &quot;nelze odinstalovat x&quot; pro balíky distutils
<p>zabývám se dědičným souborem dockerfile. zde je <em>velmi zjednodušená</em> verze toho, co se zabývám:</p><pre><code>from ubuntu:14.04 run apt-get -y update &amp;&amp; apt-get -y install \ python-pip \ python-numpy # ...and many other packages run pip install -u pip run pip install -r /tmp/requirements1.txt # includes e.g., numpy==1.13.0 run pip install -r /tmp/requirements2.txt run pip install -r /tmp/requirements3.txt </code></pre><p>nejprve je několik balíčků instalováno pomocí <code>apt</code> a několik balíčků je instalováno pomocí <code>pip</code>. <code>pip</code> verze 10 byla vydána a <a href="https://pip.pypa.io/en/stable/news/#deprecations-and-removals">část tohoto vydání</a> je toto nové omezení:</p><blockquote> <p>byla odstraněna podpora pro odinstalaci projektů, které byly nainstalovány pomocí distutils. instalované projekty distutils neobsahují metadata označující, které soubory patří k této instalaci, a proto je nemůžete skutečně odinstalovat, nýbrž pouze odstranit metadata s tím, že byly nainstalovány, zatímco všechny skutečné soubory zůstaly v pozadí. </p> </blockquote><p>to vede k následujícímu problému v mém nastavení. například první <code>apt</code> nainstaluje <code>python-numpy</code>. později se <code>pip</code> pokouší nainstalovat novější verzi <code>numpy</code> z např. <code>/tmp/requirements1.txt</code> a pokouší se odinstalovat starší verzi, ale kvůli novému omezení tuto verzi nemůže odstranit:</p><pre><code>installing collected packages: numpy found existing installation: numpy 1.8.2 cannot uninstall 'numpy'. it is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall. </code></pre><p>nyní vím, že v tomto bodě existuje několik řešení.</p><p>nemohu nainstalovat <code>python-numpy</code> prostřednictvím <code>apt</code>. to však způsobuje problémy, protože <code>python-numpy</code> nainstaluje několik různých balíčků jako požadavky a já nevím, zda se na tyto balíčky spoléhá jiná část systému. a ve skutečnosti existuje několik balíčků <code>apt</code> instalovaných přes dockerfile a každý z nich, který jsem odstranil, odhaluje další chybu <code>cannot uninstall x</code> a odstraňuje s sebou řadu dalších balíčků, na které se naše aplikace může nebo nemusí spoléhat. </p><p>mohu také použít volbu <code>--ignore-installed</code>, když se snažím <code>pip</code> instalovat věci, které již byly nainstalovány prostřednictvím <code>apt</code>, ale pak mám opět stejný problém s každým argumentem <code>--ignore-installed</code>, který odhaluje další věc, kterou je třeba ignorovat.</p><p>mohl bych připojit <code>pip</code> na starší verzi, která toto omezení nemá, ale nechci být navždy zaseknuta pomocí zastaralé verze <code>pip</code>. </p><p>chodím v kruzích a snažím se přijít s dobrým řešením, které zahrnuje minimální změny tohoto dědičného souboru dockerfile a umožňuje aplikaci, kterou tento soubor implementujeme, aby i nadále fungovala tak, jak byla. jakékoli návrhy týkající se toho, jak mohu bezpečně obejít tento problém <code>pip</code> 10, protože nejsou schopny instalovat novější verze balíčků <code>distutils</code>? děkuji!</p><h1>aktualizace:</h1><p>neuvědomil jsem si, že <code>--ignore-installed</code> by mohlo být použito bez balíčku jako argument pro ignorování všech nainstalovaných balíčků. uvažuji o tom, zda to pro mě může být dobrá volba, a ptali jsme se na to <a href="https://stackoverflow.com/q/49932926/3642398">zde</a> .</p>
<p>toto je řešení, s nímž jsem skončil, a naše aplikace fungují ve výrobě bez problémů po dobu téměř jednoho měsíce s touto opravou na místě:</p><p>jediné, co jsem musel udělat, bylo přidat</p><p><code>--ignore-installed</code></p><p>do <code>pip install</code> řádků v mém dockfile, které vykazovaly chyby. použitím stejného příkladu dockerfile z mé původní otázky by pevný dockerfile vypadal jako:</p><pre><code>from ubuntu:14.04 run apt-get -y update &amp;&amp; apt-get -y install \ python-pip \ python-numpy # ...and many other packages run pip install -u pip run pip install -r /tmp/requirements1.txt --ignore-installed # don't try to uninstall existing packages, e.g., numpy run pip install -r /tmp/requirements2.txt run pip install -r /tmp/requirements3.txt </code></pre><p>dokumentace, kterou jsem mohl najít pro <code>--ignore-installed</code>, byla podle mého názoru nejasná (<code>pip install --help</code> jednoduše říká: „ignorujte nainstalované balíčky (místo toho přeinstalovat).&ldquo;) a zeptal jsem se na potenciální nebezpečí tohoto příznaku <a href="https://stackoverflow.com/q/49932926/3642398">zde</a> , ale zatím jsem se nedostal uspokojující odpověď. pokud však dojde k nějakým negativním vedlejším účinkům, naše výrobní prostředí ještě nevidí jejich důsledky a myslím si, že riziko je nízké/žádné (alespoň to byla naše zkušenost). byl jsem schopen potvrdit, že v našem případě, když byl tento příznak použit, nebyla stávající instalace odinstalována, ale že byla vždy použita novější instalace. </p><h1>aktualizace:</h1><p>chtěl jsem zdůraznit <a href="https://stackoverflow.com/questions/53807511/pip-cannot-uninstall-package-it-is-a-distutils-installed-project/53807588#53807588">toto</a> odpověď od @ivan\_pozdeev. poskytuje některé informace, které tato odpověď nezahrnuje, a také nastiňuje některé potenciální vedlejší účinky mého řešení. </p>
<p>předejte <code>--allow-unauthenticated</code> možnost <code>apt-get</code> jako v:</p><pre><code>sudo apt-get --allow-unauthenticated upgrade </code></pre><p>z manuálové stránky uživatele <code>apt-get</code>:</p><blockquote> <p>--allow-neautenticated<br> ignorujte, pokud balíčky nemohou být ověřeny a nevyzvěte to. to je užitečné pro nástroje, jako je pbuilder. konfigurační položka: apt :: get :: allowunauthenticated.</p> </blockquote><p>toto nastavení můžete nastavit jako trvalé pomocí vlastního konfiguračního souboru na adrese <code>/etc/apt/apt.conf.d/</code> dir. název souboru může být <code>99myown</code> a může obsahovat tento řádek:</p><pre><code>apt::get::allowunauthenticated "true"; </code></pre><p>tímto způsobem nemusíte tuto možnost používat pokaždé, když chcete nainstalovat software. <strong>poznámka: nedoporučuji ve výchozím nastavení tuto možnost, obchází kontroly podpisů, které by mohly protivníkovi umožnit napadnout počítač.</strong></p> <p>kromě metody <code>dpkg</code> můžete zkontrolovat závislosti balíčků v úložišti:</p><pre><code>apt-cache depends package-name </code></pre><p><strong> editovat </strong> aktualizováno s doporučením @ tino. @ tigranův komentář již neplatí.</p> 1. No ale ten autoremove přece napřed vypíše co vše se bude odstraňovat a vyzve tě k odsouhlasení, už tady jsi udělal chybu...2. Autoremove by nikdy nemělo nabídnout k odstranění balíky které jsou k něčemu potřeba, v opačném případě máš ten systém nabořený.3. Takže se stejně reinstalaci nevyhneš. Máš aspoň oddíl /home zvlášť? Můžeš ho zachovat.Proč si systém nezálohuješ? Ušetřil by sis zbytečné reinstalace při každém problému...![](/Client.Images/smileys/6.gif) <h1>otevřete terminál a zadejte příkazy jeden po druhém:</h1><pre><code>sudo apt-get clean cd /var/lib/apt sudo mv lists lists.old sudo mkdir -p lists/partial sudo apt-get clean sudo apt-get update </code></pre><p><strong>aktualizace:</strong> v některých novějších verzích to nemusí pomoci, což může vyžadovat alternativní řešení, jako je řešení v jiné odpovědi, nebo to, které se zdá být v některých případech pod ubuntu 16.04:</p><pre><code>sudo apt-get update sudo apt-get dist-upgrade </code></pre> reinstall <p>ubuntu obsahuje gnu tar, který rozeznává formát sám! jeden příkaz pracuje s jakoukoli podporovanou kompresní metodou na <a href="http://www.gnu.org/software/tar/manual/tar.html#sec131">manuální</a> .</p><pre><code>tar xf archive.tar.xz tar xf archive.tar.gz tar xf archive.tar </code></pre><p>atd. pokud dehet dává <code>cannot exec</code> chyba, možná budete muset <code>sudo apt install xz-utils</code> za prvé.</p> <p>můžete použít některou z těchto dvou jednoplášťových linek. oba přinášejí přesně stejný výkon na mém stroji a jsou přesnější než všechna dosud navrhovaná řešení (6. července 2014) v této otázce.</p><p><strong> pomocí <code>apt-mark</code>: </strong></p><pre><code>comm -23 &lt;(apt-mark showmanual | sort -u) &lt;(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^package: //p' | sort -u) </code></pre><p><strong> pomocí <code>aptitude</code>: </strong></p><pre><code>comm -23 &lt;(aptitude search '~i !~m' -f '%p' | sed "s/ *$//" | sort -u) &lt;(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^package: //p' | sort -u) </code></pre><p>jen velmi málo balíčků stále propadá trhlinami, ačkoliv mám podezření, že je uživatel skutečně nainstaloval <em> jsou</em>, a to buď hned po instalaci prostřednictvím nastavení lokalizace jazyka, nebo např. prostřednictvím instalátoru kodeků totem. také se zdá, že se hromadí i verze linuxových záhlaví, i když jsem nainstaloval pouze metapackage, který není specifický pro verzi. příklady:</p><pre><code>libreoffice-help-en-gb openoffice.org-hyphenation gstreamer0.10-fluendo-mp3 linux-headers-3.13.0-29 </code></pre><p><strong> jak to funguje: </strong></p><ol> <li>získejte seznam ručně nainstalovaných balíčků. pro aptitude další <code>sed</code> odstraní zbývající mezeru na konci řádku.</li> <li>seznam nainstalovaných balíčků získáte hned po nové instalaci.</li> <li>porovnejte soubory, vydejte pouze řádky v souboru 1, které nejsou v souboru 2.</li> </ol><p><strong> ostatní možnosti také nefungují: </strong></p><ul> <li>za použití <code>ubuntu-14.04-desktop-amd64.manifest</code> soubor ( <a href="http://releases.ubuntu.com/releases/trusty/ubuntu-14.04-desktop-amd64.manifest">zde</a> pro ubuntu 14.04) místo <code>/var/log/installer/initial-status.gz</code>. další balíčky jsou zobrazeny jako ručně nainstalované, i když nejsou.</li> <li>použitím <code>apt-mark showauto</code> namísto <code>/var/log/installer/initial-status.gz</code>. <code>apt-mark</code> například nezahrnuje balíček xserver-xorg, zatímco druhý soubor ano.</li> </ul><p>jako reference jsem použil různé další příspěvky stackexchange, žádné však nefungují a výše uvedené řešení:</p><ul> <li> <a href="https://unix.stackexchange.com/a/3624/49168">aptitude + manifest</a> </li> <li> <a href="https://unix.stackexchange.com/a/80520/49168">initial-status.gz + apt-mark showauto</a> </li> </ul><p>oba obsahují více balíčků než výše uvedené řešení.</p><p><strong> úprava: co dělat, pokud jste upgradovali z předchozí verze: </strong></p><p>pokud jste upgradovali ubuntu z jednoho vydání na další, budete pravděpodobně muset tento proces upravit. v takovém případě bych kromě souboru initial-status.gz z aktuální verze zkontroloval soubor manifestu novější verze (viz výše). můžete to snadno udělat pouhým přidáním dalšího srovnání. použití pouze souboru manifestu nebude fungovat, protože soubor manifestu bohužel neobsahuje vše, co soubor initial\_status.gz obsahuje (zaškrtl jsem).</p> <p>můžeš použít <code>apt-get</code> k instalaci konkrétní verze balíčku, pokud je v archivu, o kterém apt ví. z <code>apt-get</code> manpage:</p><blockquote> <p>konkrétní verzi balíčku lze vybrat pro instalaci sledováním názvu balíčku se rovná a verzi balíčku, kterou chcete vybrat. to způsobí, že bude tato verze lokalizována a vybrána pro instalaci. alternativně lze specifickou distribuci vybrat následováním názvu balíčku lomítkem a verze distribuce nebo názvu archivu (stabilní, zmrazené, nestabilní).</p> </blockquote><p>můžete například:</p><pre><code>sudo apt-get install apache2=2.2.20-1ubuntu1 </code></pre><p>uvědomte si, že v tomto případě budete možná muset udělat nějaké řešení závislosti, ale pokud dojde k problémům, apt-get vám řekne, co je způsobuje. v mém systému 11.10 bych to musel udělat takto:</p><pre><code>sudo apt-get install apache2=2.2.20-1ubuntu1 \ apache2.2-common=2.2.20-1ubuntu1 \ apache2.2-bin=2.2.20-1ubuntu1 \ apache2-mpm-worker=2.2.20-1ubuntu1 </code></pre><p>dostupné verze balíčku můžete zobrazit takto:</p><pre><code>sudo apt list -a apache2 </code></pre> samozřejmě.. jako na každém jiném RPi..<https://www.raspberrypi.org/documentation/usage/python/> "Nevěřící" Tomáši.Pokud takto "skáčeš" mezi verzemi, musíš před instalací další vždy smazat konfiguraci (= nastavení) té předchozí. Pouhá odinstalace nestačí, protože ta "stará" konfigurace tam zůstane a dělá "neplechu"...Svoji konfiguraci programy většinou ukládají buďto do složky v umístení C:/Users/uživatel/AppData/Localnebo v C:/Users/uživatel/AppData/Roaming kterou je nutno po odinstalaci ještě smazat.Nebo do registru windows, což vyhledat (a smazat) je už poněkud obtížnější.Určitým východiskem je pořídit si program typu Revo Unistaller který to dokáže najít a komplet odinstalovat a"vyčistit" sám. Ovšem je třeba daný program už pomocí něho instalovat. Revo si zapíše kam se co instalovalo a pak, pomocí tohoto svého záznamu provede odinstalaci včetně konfigurace a záznamů v registru. Tím pádem se to nemusí hledat ručně...![](/Client.Images/smileys/6.gif)