Python: Wie aktualisiert man alle Pakete mit pip?
pip hat keinen Befehl upgrade-all. Also kopiert jeder irgendwoher einen
Shell-Einzeiler. Hier die bessere Variante — und der Nachweis für den Schaden,
den die Einzeiler hinterlassen können.
Einen eingebauten Befehl gibt es nicht
pip install --upgrade nimmt Paketnamen entgegen, und es gibt keine Möglichkeit
“alle” zu sagen. Diese Lücke ist Absicht — alles auf einmal zu aktualisieren
ist selten das, was ein laufendes Projekt will. Der Bedarf kommt trotzdem auf,
besonders in einer Wegwerf-Umgebung.
Zuerst nachsehen
user@pc:~$ pip list --outdated
Package Version Latest Type
certifi 2022.9.24 2026.7.22 wheel
charset-normalizer 2.1.1 3.5.1 wheel
idna 3.3 3.19 wheel
requests 2.28.1 2.34.2 wheel
urllib3 1.26.12 2.7.0 wheel
Das lohnt sich für sich genommen, bevor du irgendetwas veränderst.
Der Einzeiler, den alle kopieren
user@pc:~$ pip freeze | cut -d= -f1 | xargs pip install -U
Er funktioniert oft genug, um weitergereicht zu werden, und hat zwei Probleme.
Das erste ist pip freeze. Dessen Aufgabe ist es, eine reproduzierbare
Requirements-Datei zu erzeugen, es gibt also mehr aus als bloße Namen:
editierbare Installationen als -e ..., VCS-Auschecken als vollständige
git+https://...-URLs und lokale Pakete als Dateipfade. cut -d= -f1 macht
aus jedem davon etwas, das kein Paketname ist, und pip install -U scheitert
danach entweder oder installiert das Falsche.
Nimm stattdessen die maschinenlesbare Ausgabe:
user@pc:~$ pip list --outdated --format=json
[{"name": "certifi", "version": "2022.9.24", "latest_version": "2026.7.22", ...
Daraus bekommst du genau die Namen — und nur die, die tatsächlich veraltet sind:
user@pc:~$ pip list --outdated --format=json \
| python -c "import json,sys; print(' '.join(p['name'] for p in json.load(sys.stdin)))"
certifi charset-normalizer idna requests urllib3
Das übergibst du einem einzigen pip install --upgrade und bist fertig:
user@pc:~$ pip install --upgrade certifi charset-normalizer idna requests urllib3
Beachte das Wort einzigen. Darauf kommt es an, und darin liegt das zweite Problem.
Einzeln aktualisieren kann die Umgebung zerlegen
Die meisten Einzeiler rufen pip install -U einmal pro Paket auf. pip löst
Abhängigkeiten aber pro Install-Befehl auf. Eine Schleife mit n Befehlen ist
also nicht dasselbe wie ein Befehl mit n Paketen.
So sieht das aus, wenn es schiefgeht. Ausgangspunkt ist eine stimmige Umgebung,
in der requests 2.28.1 ein urllib3 < 1.27 verlangt:
installing requests 2.28.1 again, which needs urllib3 < 2:
No broken requirements found.
Jetzt nur urllib3 aktualisieren, genau wie es eine Schleife tun würde:
requests 2.28.1 requires urllib3<1.27,>=1.21.1, but you have urllib3 2.7.0 which is incompatible.
pip warnt während der Installation, und die Umgebung ist jetzt kaputt. Wenn diese Warnung in hundert Zeilen Ausgabe vorbeigescrollt ist, sagt es dir nichts mehr — bis zur Laufzeit.
Der Befehl, der es nachträglich findet, ist einer den kaum jemand kennt:
user@pc:~$ pip check
requests 2.28.1 has requirement urllib3<1.27,>=1.21.1, but you have urllib3 2.7.0.
Führ pip check nach jeder Sammelaktualisierung aus. Es ist sofort fertig und
sagt entweder No broken requirements found oder benennt das Problem genau.
Was ich tatsächlich machen würde
Bei einem echten Projekt aktualisiert man nicht alles. Man pinnt die
Abhängigkeiten, aktualisiert bewusst und überlässt die Arbeit einem Werkzeug,
das den ganzen Satz auf einmal auflöst —
pip-tools, Poetry oder uv tun genau
das und erzeugen dabei eine Lock-Datei, damit das Ergebnis reproduzierbar ist.
Zwei Kleinigkeiten helfen in jedem Fall:
Arbeite in einer virtuellen Umgebung. Alles in einem System-Python zu
aktualisieren kann Werkzeuge zerstören, die aus der Paketverwaltung deiner
Distribution stammen.
venv ist Teil der
Standardbibliothek.
Erst schauen, dann springen. pip install --dry-run --upgrade ... zeigt
dir, was sich ändern würde, ohne es zu ändern. Bei einer langen Liste sind die
zehn Sekunden gut angelegt.
Für eine Wegwerf-Umgebung
Wenn es wirklich eine Wegwerf-Umgebung ist und einfach alles aktuell sein soll:
user@pc:~$ pip list --outdated --format=json \
| python -c "import json,sys; print(' '.join(p['name'] for p in json.load(sys.stdin)))" \
| xargs -r pip install --upgrade
user@pc:~$ pip check
Eine Auflösung, kein Zerlegen von freeze, und eine Prüfung am Ende. Das -r
bei xargs verhindert, dass pip install --upgrade ohne Argumente läuft, wenn
nichts veraltet ist.
Hinweis zu Netcup (Werbung)
Der deutsche Hoster Netcup bietet unter anderem günstige und zugleich leistungsstarke Webhosting Pakete, KVM-basierte Root Server und dezidierte Server an. Mit unseren Gutscheincodes kannst du noch mehr Geld sparen (6€ bei deiner ersten Bestellung, 30% Rabatt auf alle KVM-basierten Root Server, ...).