Apa yang dilakukan instruksi 'apt-get remove' ini?

10

Apa yang dilakukan kode berikut?

Saya menemukannya di internet jadi saya menyalinnya dan menempelkannya ke terminal tetapi ketika saya menginstal kernel baru itu hanya mendeteksi yang lama.

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')
medo_alouane
sumber
Bagian kedua adalah ekspresi reguler, mendefinisikan bagaimana nama file akan terlihat tetapi tidak persis nama file itu. Apakah itu menginstal kernel yang merupakan tujuan Anda atau apakah ia mengetahui persis apa yang dihapus perintah?
Niklas Lindskog
Kode ini tidak akan menginstal kernel apa pun, tetapi menghapusnya ! Saya tidak melihat persis apa yang dilakukan oleh sed-command ini, tetapi memproses output dari dpkg -l 'linux-image-*', yang mencantumkan semua paket kernel yang terinstal dan menyaring beberapa dari mereka untuk dihapus oleh apt-get remove.
Byte Commander
16
Aturan praktis yang sangat baik untuk dijalani: jika Anda tidak tahu apa kode itu, jangan masukkan kode itu ke Terminal sampai seseorang yang tahu apa itu memberitahu Anda. Jika Anda mencoba untuk mendapatkan kernel terbaru, Anda mungkin ingin melihat askubuntu.com/questions/119080/… alih-alih menggunakan kode yang tidak Anda mengerti.
Kolonel Trogdor
Kernel tua yang duduk di disk tidak menimbulkan masalah, kecuali untuk mengambil ruang disk, dan membuat update-grub(paket postinst) lebih lambat. Jika Anda khawatir Anda tidak benar-benar mem-boot kernel yang Anda coba tingkatkan, jalankan uname -a, atau bahkandmesg | less
Peter Cordes
7
"Saya menemukannya di internet jadi saya menyalinnya dan menempelkannya ke terminal" TIDAK, TIDAK, TIDAK, TIDAK. Anda akhirnya akan melakukan hal-hal mengerikan secara tidak sengaja. Menjalankan kode yang Anda tidak mengerti menghasilkan hal-hal buruk seperti nuking sistem Anda, dan anak-anak anjing ditendang.
Journeyman Geek

Jawaban:

12

Mari kita pecahkan kode satu per satu (untuk sistem saya):

$ 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

Jadi ini tidak akan menghasilkan apa-apa:

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

Seperti yang Anda lihat , itu sangat dekat dengan menghapus paket meta kernel saya saat ini linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image (terima kasih untuk sed '/[0-9]/!d'baris terakhir ini ), yang salah.

Singkatnya, karya ini sedmemiliki beberapa masalah. Anda harus menghindarinya untuk menghapus kernel lama Anda.

EDIT:

Saya sudah mengatakan bahwa sedperintah memiliki masalah. Demi ekstensi saya akan menghapus dua baris terakhir dengan bentuk yang sebenarnya harus berfungsi dalam skenario saya saat ini.

Dua baris terakhir dalam bentuk yang dimodifikasi:

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

Begitu:

$ 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

Itu sangat berdarah !!

Sekarang menunjukkan apa yang akan dilakukan pada sistem saya, --dry-rundengan apt-get removeperintah penuh :

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

Seperti yang Anda lihat itu akan menghapus semua kernel saya saat ini, juga perhatikan bahwa ini hanya simulasi untuk mencocokkan skenario saya saat ini dan yang asli seddapat ditingkatkan.

** Perhatikan bahwa kode aktual akan berfungsi jika melakukan rebootupgrade kernel setelah yang sudah disebutkan Oli .

EDIT2:

Berikut ini adalah skrip sederhana namun tangguh yang akan mempertimbangkan semua situasi dan menghapus kernel lama yang sebenarnya:

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

Jika Anda memiliki versi yang lebih baru dari versi saat ini, ini akan memberi Anda peringatan untuk memulai kembali komputer Anda terlebih dahulu. Perhatikan juga bahwa kernel yang lebih lama disimpan karena alasan yang bagus yaitu jika Anda entah bagaimana mengacaukan kernel Anda saat ini membuat sistem Anda tidak stabil maka Anda harus dapat boot ke kernel yang lebih tua.

heemayl
sumber
Um, tunggu, apa? Anda mengganti kode asli yang berfungsi dengan beberapa kode lain yang Anda pikir "benar-benar harus (!!) ada di sana", amati bahwa kode "tetap" Anda rusak dan akan menghapus kernel Anda saat ini, dan dengan demikian menyimpulkan bahwa kode aslinya adalah " sangat berdarah !! "? WTF? -1.
Ilmari Karonen
Tentu saja ada alasan yang valid untuk mengkritik kode asli, seperti yang ditunjukkan misalnya dalam jawaban Oli, dan saya yakin kode sed dapat dibuat lebih kuat. Tetapi fakta itu tetap bahwa, dalam keadaan normal (misalnya Anda telah reboot setelah upgrade kernel terakhir Anda), kode asli berfungsi, sedangkan versi modifikasi Anda tidak.
Ilmari Karonen
1
Pertama-tama Anda tidak boleh menggunakan kata terakhir yang telah Anda gunakan..Sekarang, apakah Anda benar-benar menjalankan kode yang sebenarnya? menghapus apt-getbagian dan output apa yang Anda dapatkan?
heemayl
@IlmariKaronen: yah, aku yang kedua bersamamu dalam beberapa hal, aku telah memodifikasi jawabannya ..
heemayl
Mengapa, ya, saya tidak menjalankan perintah Anda diubah (versi yang tidak crash karena kurung hilang setelah (([a-z]|-)*, yaitu) tanpa apt-getbagian sebelum mengkritik itu. Pada sistem saya, itu output baris berikut: 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. Apakah itu benar-benar apa yang Anda inginkan? (Juga, poin bonus jika Anda bisa mengetahui kernel mana yang sebenarnya telah saya instal.)
Ilmari Karonen
12

Ini adalah upaya untuk menghapus kernel yang bukan yang sekarang.

Ada banyak bit kode di luar sana yang melakukan sesuatu seperti ini dan ini bukan contoh yang baik . Ini dapat dengan mudah menghapus kernel yang lebih baru dari saat ini dan karena itu paket meta yang menginstal ( linux-genericet al) jika Anda memiliki upgrade dan tidak reboot.

Oli
sumber
2
Dan ini sama sekali bukan ide yang bagus. Kernel yang lebih tua disimpan karena suatu alasan, secara default hanya ada 2 yang lama dan yang sekarang.
Barafu Albino