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, ...).