tldr;
우분투에선 이게 답이다.
ppip3 list -o --user | awk '{if(NR>=3)print}' | cut -d' ' -f1 | xargs -n1 python3 -m pip install -U --user
ArchLinux 에선 pip 이 늘 최신이므로, 굳이 python -m pip
을 할 필요가 없다.
pip list -o --user | awk '{if(NR>=3)print}' | cut -d' ' -f1 | xargs -n1 pip install -U --user
목록만 보고 싶다면, xargs 를 빼면 된다.
pip list -o --user | awk '{if(NR>=3)print}' | cut -d' ' -f1
여기에 더하여, 2020 11월 현재, 우분투에선 pip 이 뭔가 의존성에 관련하여 변경된 부분이 있다고 한다. 위 명령을 실행하면, --use-feature=2020-resolver
를 붙이라는 경고가 나올 때가 있다.
따라서 아예 첨부해주면 다음과 같다.
ppip3 list -o --user | awk '{if(NR>=3)print}' | cut -d' ' -f1 | xargs -n1 python3 -m pip install -U --user --use-feature=2020-resolver
마지막으로, 몇몇 꾸러미는 과거판에 종속되어 있는 경우가 있다. 예를 들어, jedi 가 의존하는 parso 는 0.7.x 인데, 현재 0.8 까지 나와 있어서, 설치 시에 오류가 나온다. (실제로 작동이 안되는지 아닌지는 모르겠다.)
이걸 피해가려면, 설치 시에 이런 애들을 빼줘야 하는데.. (헌데, 이건 일단 판올림 명령을 내려야만 알 수 있기에 좀 애매하긴 하다. 명령 전에 알 수 있는 방법도 있긴 할텐데?)
간단하게, grep 로 이런 애들을 빼주면 되겠다.
ppip3 list -o --user | awk '{if(NR>=3)print}' | cut -d' ' -f1 | egrep -v 'packageA|packageB|....' | xargs -n1 python3 -m pip install -U --user # 또는, ppip3 list -o --user | awk '{if(NR>=3)print}' | cut -d' ' -f1 | egrep -v 'packageA|packageB|....' | xargs -n1 python3 -m pip install -U --user --use-feature=2020-resolver
2020년 11월 현재, 내 환경에서 이 문제가 있는 꾸러미는 parso 와 lazy-object-proxy 다. parso 는 jedi 가, lazy-object-proxy 는 astroid 가 참고하고 있다.
예전에도 같은 내용에 대해 글을 쓴 적이 있었는데, 그 내용보단 이게 훨씬 낫다. (아래 내용에는 꽃삽질이 포함되어 있다. 최종 명령은 바로 위에 있고, 그를 찾기 위한 삽질기가 아래에 이어진다.)
이를 위한 몇몇 1행 명령(Oneliner)들을 찾을 수 있었는데, 그 중 가장 짧고(?) 괜찮아보이는 명령을 택했다.
다만, 원글을 쓴 이는 pip3 를 바로 실행했으나, 우분투에선 이게 살짝 문제가 될 수 있으므로, pip3 대신 python3 -m pip
을 실행하기로 한다.
또, 모든 Pip 꾸러미를 대상으로 하지 않고, 사용자가 설치한 꾸러미만을 판올림하도록 한다.
python3 -m pip list -o --user --format columns| cut -d' ' -f1|xargs -n1 python3 -m pip install -U --user
** python3 -m pip
을 ppip3 로 Alias 화 하여 사용하고 있었는데, 위 명령에서 앞 부분은 ppip3 로 바꿔도 되지만, xargs 뒤는 ppip3 로 바꾸면 안된다. (sub shell 이 되어, export 가 불가능하다.)
???
그런데, 위 명령대로 하면 살짝 오류가 발생한다. pip list 의 결과를 3행부터 취해야만 하는데, 그에 대한 고려가 없어서 엉뚱한 결과를 보게 된다. (그렇다고 문제가 있지는 않지만, 그래도 불필요한 오류가 생기니 바로 잡는게 좋겠지?)
다른 명령을 찾아봤더니, 좀 더 복잡한 이런게 있었다. (미리 말하면, 아래 내용대로 넣으면 또 다른 오류가 발생한다.)
pip3 list -o | cut -f1 -d' ' | tr " " "\n" | awk '{if(NR>=3)print)' | cut -d' ' -f1 | xargs -n1 pip3 install -U
이참에 cut 과 tr awk 에 대해 간단한 설명을 덧붙여보도록 한다.
먼저, ppip3 list -o
의 결과는 다음과 같다.
ppip3 list -o --user | cut -f1 -d' ' Package Version Latest Type ------------ ------- ------ ----- ipython 7.18.0 7.19.0 wheel jupyter-core 4.6.3 4.7.0 wheel
여기에서 필요한 부분은 첫번째 열인 Package 항목이므로, 여기만을 출력하게 할 때 cut 이 필요하다.
cut 에서 -f1 은 첫번째 열을 선택하라는 의미고, -d’ ‘ 은, 열 구분자로 공백(‘ ‘)을 쓰겠다는 뜻이 된다.
$ ppip3 list -o --user | cut -f1 -d' ' Package ------------ ipython jupyter-core
그런데, 여전히 불필요한 내용이 보인다. 첫째행과 둘째행, 즉 ‘Package’ 와, 그 아래 있는 점선. 이 두가지를 제외해야만하는데, 그때는 awk 의 힘을 빌려야 한다.
ppip3 list -o --user | cut -f1 -d' ' | awk '{if(NR>=3)print}' ipython jupyter-core
이러면 끝이다. 내가 인용한 원 명령에는 awk 부분 문법 오류가 있다.(뒤에 } 가 빠져있다.) 또, tr 도 사용했는데, 왜 사용했는지 의문. 그것도 두번이나 사용을 했는데..??
awk if 를 사용하여, 3행 이상(NR>=3)만 출력하도록 했다. 이제 마지막으로 판올림 명령만 붙여주면 된다.
ppip3 list -o --user | awk '{if(NR>=3)print}' | cut -d' ' -f1 | xargs -n1 python3 -m pip install -U --user
바로 위에서 한 것처럼, awk 와 cut 은 서로 바꿔줘도 아무런 상관이 없다. 속도 차는 날 수 있을 지언정.
이게 최종 명령이 되겠다.
혹시 사용하다가 tr 이 필요하게 되면 다시 정리해보기로 한다.
참고로, tr 에 대한 자세한 설명은 여기에 나와있다. 간단하게 생각해서, tr(translate)은, regex 의 substitute 와 유사하다. 즉, 앞에 있는 것을 뒤에 있는 것으로 바꾸라는 의미가 된다. tr " " "\n"
은 공백을 행바꿈문자로 변환하라는 뜻!