
다음 코드는 무엇을 합니까?
인터넷에서 찾아서 복사해서 터미널에 붙여넣었는데 새 커널을 설치하면 이전 커널만 감지됩니다.
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
업그레이드하고 재부팅하지 않은 경우 최신 커널과 설치하는 메타 패키지(외)를 쉽게 제거할 수 있습니다 .