이 'apt-get 제거' 명령은 무엇을 합니까?

이 'apt-get 제거' 명령은 무엇을 합니까?

다음 코드는 무엇을 합니까?

인터넷에서 찾아서 복사해서 터미널에 붙여넣었는데 새 커널을 설치하면 이전 커널만 감지됩니다.

sudo apt-get remove --purge $(dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d')

답변1

(내 시스템의 경우) 코드를 하나씩 분석해 보겠습니다.

$ dpkg -l 'linux-image-*'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                          Version             Architecture        Description
+++-=============================-===================-===================-================================================================
un  linux-image-3.0               <none>              <none>              (no description available)
ii  linux-image-3.13.0-32-generic 3.13.0-32.57        amd64               Linux kernel image for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-extra-3.13.0-32-g 3.13.0-32.57        amd64               Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-generic           3.13.0.32.38        amd64               Generic Linux kernel image


$ dpkg -l 'linux-image-*' | sed '/^ii/!d'
ii  linux-image-3.13.0-32-generic                         3.13.0-32.57                                        amd64        Linux kernel image for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-extra-3.13.0-32-generic                   3.13.0-32.57                                        amd64        Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP
ii  linux-image-generic                                   3.13.0.32.38                                        amd64        Generic Linux kernel image


$ uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/'
3.13.0-32



$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d"
ii  linux-image-generic                                   3.13.0.32.38                                        amd64        Generic Linux kernel image



$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d" | sed 's/^[^ ]* [^ ]* \([^ ]*\).*/\1/'
linux-image-generic



$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d" | sed 's/^[^ ]* [^ ]* \([^ ]*\).*/\1/' | sed '/[0-9]/!d'
## No output

따라서 이것은 아무 작업도 수행하지 않습니다.

$ sudo apt-get remove --purge $(dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d')

보시다시피현재 커널 메타 패키지를 제거하는 것과 매우 비슷했습니다. linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image(이 마지막 줄 덕분에 sed '/[0-9]/!d') 이는 잘못된 것입니다.

간단히 말해서 이 작품에는 sed몇 가지 문제가 있습니다. 이전 커널을 제거하려면 이를 피해야 합니다.

편집하다:

나는 이미 명령에 문제가 있다고 말했습니다 sed. 확장을 위해 현재 시나리오에서 실제로 작동해야 하는 양식의 마지막 두 줄을 제거하겠습니다.

수정된 형식의 마지막 두 줄:

sed -r 's/^[^ ]* *(([a-z]|-)*)(-[a-z]*) *(([0-9]|-)*)\..*/\1-\4\3/'

그래서:

$ dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | 
sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d' | 
sed -r 's/^[^ ]* *(([a-z]|-)*(-[a-z]*) *(([0-9]|\.|-)*)\..*/\1\-\4\3/'

출력:

linux-image-3.13.0.32-generic

정말 위험해요!!

--dry-run이제 전체 명령을 실행하여 이것이 내 시스템에 어떤 영향을 미치는지 보여줍니다 apt-get remove.

$ sudo apt-get remove --dry-run $(dpkg -l 'linux-image-*' | 
sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d' | 
sed -r 's/^[^ ]* *(([a-z]|-)*)(-[a-z]*) *(([0-9]|\.|-)*)\..*/\1\-\4\3/')


Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'linux-image-3.13.0-32-generic' for regex 'linux-image-3.13.0.32-generic'
The following package was automatically installed and is no longer required:
  linux-headers-generic
Use 'apt-get autoremove' to remove it.
The following packages will be REMOVED:
  linux-generic linux-image-3.13.0-32-generic
  linux-image-extra-3.13.0-32-generic linux-image-generic
0 upgraded, 0 newly installed, 4 to remove and 0 not upgraded.
Remv linux-generic [3.13.0.32.38]
Remv linux-image-generic [3.13.0.32.38]
Remv linux-image-extra-3.13.0-32-generic [3.13.0-32.57]
Remv linux-image-3.13.0-32-generic [3.13.0-32.57]

보시다시피 현재 커널이 모두 제거됩니다. 이는 현재 시나리오와 일치하는 시뮬레이션일 뿐이며 원본은 sed개선될 수 있습니다.

reboot** 커널 업그레이드 후 다음과 같이 수행하면 실제 코드가 작동합니다.이미 언급한 올리.

편집2:

다음은 모든 상황을 고려하고 실제 이전 커널을 제거하는 간단하면서도 강력한 스크립트입니다.

#!/bin/bash
kernels=( $(grep -Po "^linux-image-[^-]+-[^-]+-generic\b" < <(dpkg --get-selections)) )
cur_rel=$(grep -Po ".*(?=-[a-z]*$)" < <(uname -r))

for kernel in "${kernels[@]}"; do
    ker_rel=$(grep -Po "[0-9].*(?=-[a-z]*)" <<< "$kernel")
    dpkg --compare-versions "$ker_rel" gt "$cur_rel" && { echo "Please Restart your computer first"; break; }
    dpkg --compare-versions "$ker_rel" lt "$cur_rel" && sudo apt-get remove "$kernel"
done

현재 버전보다 최신 버전이 있는 경우 먼저 컴퓨터를 다시 시작하라는 경고 메시지가 표시됩니다. 또한 현재 커널을 엉망으로 만들어 시스템을 불안정하게 만드는 경우 이전 커널로 부팅할 수 있기 때문에 이전 커널이 보존된다는 점에 유의하세요.

답변2

이는 현재 커널이 아닌 커널을 제거하려는 노력입니다.

이와 같은 작업을 수행하는 코드가 많이 있습니다.이건 좋은 예가 아니야. linux-generic업그레이드하고 재부팅하지 않은 경우 최신 커널과 설치하는 메타 패키지(외)를 쉽게 제거할 수 있습니다 .

관련 정보