Hướng dẫn 'apt-get remove' này làm gì?


10

Mã sau đây làm gì?

Tôi tìm thấy nó trên internet vì vậy tôi đã sao chép nó và dán nó vào thiết bị đầu cuối nhưng khi tôi cài đặt kernel mới, nó chỉ phát hiện ra kernel cũ.

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

Phần thứ hai là một biểu thức chính quy, xác định tên tệp sẽ trông như thế nào nhưng không chính xác tên tệp đó là gì. Có phải nó đang cài đặt kernel là mục tiêu của bạn hay nó đang tìm ra chính xác những gì lệnh loại bỏ?
Niklas Lindskog

Mã này sẽ không cài đặt bất kỳ kernel nào, nhưng loại bỏ chúng! Tôi không thấy chính xác lệnh sed này làm gì, nhưng nó xử lý đầu ra của dpkg -l 'linux-image-*'nó, liệt kê tất cả các gói kernel đã cài đặt và lọc một số trong số chúng để xóa apt-get remove.
Chỉ huy Byte

16
Một nguyên tắc rất tốt để sống theo: nếu bạn không biết mã làm gì, đừng đặt mã đó vào Terminal cho đến khi ai đó biết nó nói gì với bạn. Nếu bạn đang cố gắng để có được hạt nhân cập nhật nhất, bạn có thể muốn xem tại Askubfox.com/questions/119080/, thay vì sử dụng mã mà bạn không hiểu.
Đại tá Trogdor

Các hạt nhân cũ ngồi xung quanh đĩa không gây rắc rối, ngoại trừ việc chiếm dung lượng đĩa và làm cho update-grub(gói postinst) chậm hơn. Nếu bạn lo lắng rằng bạn không thực sự khởi động kernel mà bạn đang cố nâng cấp lên, thì hãy chạy uname -ahoặc thậm chídmesg | less
Peter Cordes

7
"Tôi tìm thấy nó trên internet vì vậy tôi đã sao chép nó và dán nó vào thiết bị đầu cuối" KHÔNG KHÔNG KHÔNG KHÔNG KHÔNG KHÔNG. Bạn sẽ kết thúc làm những điều khủng khiếp một cách tình cờ. Chạy mã bạn không hiểu kết quả trong những điều khủng khiếp như làm hỏng hệ thống của bạn và chó con bị đá.
Journeyman Geek

Câu trả lời:


12

Hãy phá mã từng cái một (cho hệ thống của tôi):

$ 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

Vì vậy, điều này sẽ không làm gì:

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

Như bạn có thể thấy nó rất gần với việc loại bỏ gói meta kernel hiện tại của tôi linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image (nhờ sed '/[0-9]/!d'dòng cuối cùng này ), đó là sai.

Tóm lại, phần sednày có một số vấn đề. Bạn nên tránh nó để loại bỏ hạt cũ của bạn.

BIÊN TẬP:

Tôi đã nói rằng sedlệnh có vấn đề. Vì mục đích mở rộng, tôi sẽ xóa hai dòng cuối cùng với hình thức thực sự sẽ hoạt động trong kịch bản hiện tại của tôi.

Hai dòng cuối cùng trong một hình thức sửa đổi:

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

Vì thế:

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

Xuất sắc:

linux-image-3.13.0.32-generic

Đó là rất đáng sợ !!

Bây giờ hiển thị những gì điều này sẽ làm với hệ thống của tôi, --dry-runvới apt-get removelệnh đầy đủ :

$ 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]

Như bạn thấy, nó sẽ loại bỏ tất cả các nhân hiện tại của tôi, cũng lưu ý rằng đây chỉ là một mô phỏng để phù hợp với kịch bản hiện tại của tôi và bản gốc sedcó thể được cải thiện.

** Lưu ý rằng mã thực tế sẽ hoạt động nếu thực hiện rebootnâng cấp kernel sau như Oli đã đề cập .

EDIT2:

Dưới đây là một tập lệnh đơn giản nhưng mạnh mẽ sẽ xem xét tất cả các tình huống và loại bỏ các nhân cũ thực tế:

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

Nếu bạn có bất kỳ phiên bản nào mới hơn phiên bản hiện tại, điều này sẽ đưa ra cảnh báo khởi động lại máy tính của bạn trước. Cũng lưu ý rằng các hạt nhân cũ hơn được bảo tồn do một lý do chính đáng là nếu bạn bằng cách nào đó làm rối hạt nhân hiện tại của bạn làm cho hệ thống của bạn không ổn định thì bạn có thể khởi động vào bất kỳ hạt nhân cũ nào.


Ừm, đợi đã, cái gì? Bạn thay thế mã gốc, mã làm việc bằng một số mã khác mà bạn nghĩ rằng "thực sự nên (!!) ở đó", quan sát rằng mã "cố định" của bạn bị hỏng và sẽ xóa hạt nhân hiện tại của bạn và do đó kết luận rằng mã gốc là " rất đáng sợ !! "? WTF? -1.
Ilmari Karonen

Chắc chắn có những lý do hợp lệ để chỉ trích mã gốc, như đã chỉ ra, ví dụ như trong câu trả lời của Oli và tôi chắc chắn rằng mã sed có thể được làm cho mạnh mẽ hơn. Nhưng thực tế đó vẫn là, trong các trường hợp thông thường (ví dụ: bạn đã khởi động lại sau lần nâng cấp kernel cuối cùng), mã gốc hoạt động, trong khi phiên bản sửa đổi của bạn thì không.
Ilmari Karonen

1
Trước hết bạn không nên sử dụng từ cuối cùng bạn đã sử dụng..bây giờ, bạn đã thực sự chạy mã thực tế chưa? loại bỏ apt-getmột phần và những gì bạn đã nhận được?
heemayl

@IlmariKaronen: tốt, tôi đứng thứ hai với bạn ở một số điểm, tôi đã sửa đổi câu trả lời ..
heemayl

Tại sao, vâng, tôi đã chạy lệnh đã sửa đổi của bạn (phiên bản không bị lỗi do thiếu dấu ngoặc đơn sau (([a-z]|-)*đó, nghĩa là) mà không có apt-getphần trước khi chỉ trích nó. Trên hệ thống của tôi, nó sẽ tạo ra những dòng sau: 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. Đó thực sự là những gì bạn dự định? (Ngoài ra, điểm thưởng nếu bạn có thể tìm ra hạt nhân nào tôi thực sự đã cài đặt.)
Ilmari Karonen

12

Đây là một nỗ lực để loại bỏ các hạt nhân không phải là hiện tại.

Có rất nhiều đoạn mã ngoài kia làm một cái gì đó như thế này và đây không phải là một ví dụ tốt . Nó có thể dễ dàng loại bỏ các hạt nhân mới hơn hiện tại và do đó gói meta cài đặt ( linux-genericet al) nếu bạn đã nâng cấp và không khởi động lại.


2
Và đây không phải là một ý tưởng tốt. Những hạt nhân cũ hơn được giữ vì lý do, theo mặc định chỉ có 2 cũ và một hiện tại.
Barafu Albino
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.