![[小ネタ] Nushellでpipパッケージの一括更新を行う方法](https://devio2024-media.developers.io/image/upload/v1745853470/user-gen-eyecatch/x9ubsjw8fjcohdckas4h.png)
[小ネタ] Nushellでpipパッケージの一括更新を行う方法
しばたです。
私は以前の記事で紹介したEmbeddable Python環境を定期的に更新して現在まで利用し続けています。
先日常用するシェルをNushellに変えてからはじめて環境を更新したので簡単に手順をまとめてみました。
pipパッケージの一括更新方法
pipで管理しているパッケージを一括更新する方法は昔から変わらず
pip list
コマンドの結果から逐次パッケージを更新するpip freeze
コマンドの結果から逐次パッケージを更新する- 外部パッケージ(pip-review)を使う
が主流の様です。
pip list
コマンドには更新があるパッケージだけを対象とする--outdated (-o)
オプションがあり、加えて--format
オプションで出力形式をJSONにすることもできます。
Nushellで扱うにはうってつけなので今回はpip list
コマンドを使った方法を採用します。
Nushellでpipパッケージの一括更新を行う
pip list
コマンドを次の様に実行してやればJSONで出力し、さらにNushellのTable型オブジェクトに変換できます。
# --format jsonでJSON出力できるので、from jsonコマンドで変換してやる
pip list -o --format json | from json
実行例はこんな感じです。
C:\aws\cfn-python-lint\
フォルダ配下にEmbeddable Python環境がある場合
あとはこの結果から各モジュールをpip install -U
コマンドで更新してやればOKです。
# eachコマンドを使って一括アップデート
pip list -o --format json | from json | each {pip install -U $in.name}
each
コマンドの実行結果はListになるのでコンソール上の表示には連番が付きます。
コマンド実行後に再チェックすると全てのモジュールが更新済みであることがわかります。
更新対象がなくなっている(空リストになっている)
無事一括更新ができました。
余談1 : JSON出力できるならPowerShellでも良いしjqを使っても構わない
身も蓋もない話ですが、JSONの取り扱いが簡単にできる環境であればNushellでなくとも同様の事は実現できます。
例えばPowerShellにはConvertFrom-Json
コマンドがありますし、Windows環境でもjqは使えます。
今回のコマンドはPowerShellだと次の内容で代替できます。
# ConvertFrom-JsonコマンドでJSONを変換
pip list -o --format json | ConvertFrom-Json
# 更新にはForEach-Objectを使う
pip list -o --format json | ConvertFrom-Json | ForEach-Object {pip install -U $_.name}
余談2 : Windows環境の場合UTF-8 modeを有効にしておいた方が良い
比較的新しいバージョン(v22)からpip inspect
コマンドが追加されPython環境に関する情報を高速にJSONで取得できます。
こちらは今回のpip list
コマンドよりも多くの情報を取得できるのですが、私の環境(日本語版Windows 11)で実行するとエラーになることがありました。
# pip inspectコマンドでエンコーディング周りのエラーが出ることがある
pip inspect | from json
UnicodeEncodeError: 'cp932' codec can't encode character '\xf6' in position 9: illegal multibyte sequence
Error: nu::parser::non_utf8_custom
エラーメッセージから明らかに日本語環境のエンコーディング(CP932)が悪さをしていることが見て取れます。
この様な場合PYTHONUTF8
環境変数を設定しUTF-8 modeを有効することで問題を回避できます。
# UTF-8 modeを有効にしてエンコーディングの問題を回避
$env.PYTHONUTF8 = 1
pip inspect | from json
UTF-8 modeを有効にした結果、エラーなく期待通りの値を取得できています。
UTF-8 modeはPythonが内部的に使用するエンコーディングをUTF-8にする機能で、以下の記事が詳しいのでご一読ください。
最後に
簡単ですが以上となります。
ちょっとした小ネタですが誰かの役に立てば幸いです。