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


10

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

인터넷에서 찾았으므로 복사하여 터미널에 붙여 넣었지만 새 커널을 설치하면 이전 커널 만 감지합니다.

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')

두 번째 부분은 정규식으로, 파일 이름의 모양을 정의하지만 파일 이름이 정확히 일치하지는 않습니다. 목적에 맞는 커널을 설치 중입니까, 아니면 명령이 정확히 무엇을 제거하고 있습니까?
Niklas Lindskog

이 코드는 커널을 설치 하지 않지만 제거 합니다! 이 sed-command가 정확히 무엇을하는지 모르겠지만 dpkg -l 'linux-image-*'설치된 모든 커널 패키지를 나열하고의 일부를 필터링하여에 의해 삭제되도록 의 출력을 처리합니다 apt-get remove.
바이트 사령관

16
살기 좋은 규칙 : 코드가 무엇인지 모르는 경우 코드가 무엇인지 아는 사람이 알려줄 때까지 해당 코드를 터미널에 넣지 마십시오. 최신 커널을 얻으려면 이해하지 못하는 코드를 사용하는 대신 askubuntu.com/questions/119080/… 을 참조하십시오.
Trogdor 대령

디스크에 앉아있는 오래된 커널은 디스크 공간을 차지하고 update-grub(패키지 postinst)를 느리게 만드는 것 외에는 문제가 없습니다 . 실제로 커널을 부팅하지 않았다고 걱정하는 경우 업그레이드, 실행 uname -a또는 실행하려고했습니다dmesg | less
Peter Cordes

7
"인터넷에서 찾았으므로 복사해서 터미널에 붙여 넣었습니다."NO NO NO NO NO. 우연히 끔찍한 일을하게 될 것입니다. 코드를 이해하지 못하면 시스템을 핵 공격하고 강아지를 쫓아내는 것과 같은 끔찍한 일이 발생합니다.
Journeyman Geek

답변:


12

내 시스템을 위해 코드를 하나씩 나누자.

$ 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/'

Outpus :

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을 향상시킬 수 있습니다.

** Oli가 이미 언급 한대로reboot 커널 업그레이드 후 수행 할 경우 실제 코드는 작동합니다 .

EDIT2 :

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

#!/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

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


잠깐만 원래의 작동 코드를 "실제로 있어야한다 (!!)"라고 생각하는 다른 코드로 바꾸고, "고정 된"코드가 깨져서 현재 커널을 제거하고, 따라서 원래 코드가 " 매우 밀도가 높은 !! "? WTF? -1.
Ilmari Karonen

예를 들어 Oli의 답변에서 지적했듯이 원래 코드를 비판 해야하는 정당한 이유가 있으며 sed 코드가 더 강력해질 수 있다고 확신합니다. 그러나 사실은 정상적인 상황 (예 : 마지막 커널 업그레이드 후 재부팅)에서 원래 코드는 작동하지만 수정 된 버전은 작동하지 않습니다.
Ilmari Karonen

1
우선 마지막으로 사용한 단어를 사용해서는 안됩니다. 이제 실제 코드를 실제로 실행 했습니까? apt-get부품을 제거 하고 어떤 결과를 얻었습니까?
heemayl

@IlmariKaronen : 글쎄, 난 몇 가지 점에서 당신과 함께 두 번째, 나는 대답을 수정했습니다 ..
heemayl

왜, 그래, 내가 않은 수정 된 명령 (후 누락 된 괄호로 인한 충돌하지 않는 버전을 실행 (([a-z]|-)*포함하지 않는 것입니다,) apt-get를 비판하기 전에 부분. 내 시스템에서, 그 다음 줄을 출력 : linux-image-3.13-, linux-image-3.13-, linux-image-extra-3.13-, linux-image-extra-3.13-, linux-image-3.13.0.49-generic. 즉 정말 당신이 의도? (또한 실제로 어떤 커널을 설치했는지 알아낼 수 있다면 보너스 포인트입니다.)
Ilmari Karonen

12

이것은 현재가 아닌 커널을 제거하기위한 노력입니다.

이와 같은 작업을 수행하는 많은 코드 가 있으며 이는 좋은 예가 아닙니다 . 현재 커널보다 최신 커널을 쉽게 제거 할 수 있기 때문에 linux-generic업그레이드를하고 재부팅하지 않은 경우 설치하는 메타 패키지 등이 있습니다.


2
그리고 이것은 전혀 좋은 생각이 아닙니다. 이러한 오래된 커널은 이유를 위해 유지되며 기본적으로 2 개의 오래된 커널과 현재의 커널 만 있습니다.
Barafu Albino
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.