Apakah perintah ini untuk menghapus kernel lama aman digunakan?

21

Saat menjelajah internet untuk artikel Ubuntu, saya menemukan perintah ini:

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

Penulis mengatakan bahwa ini adalah perintah baris tunggal yang akan menghapus semua versi Linux sebelumnya, hanya menyisakan yang sekarang !

Saya sebenarnya mencari perintah seperti itu, tapi saya tidak begitu yakin seberapa aman ini. Saya ingin tahu:

  • Apakah aman untuk menjalankan perintah ini?
  • Bagaimana cara kerja perintah ini? yaitu penjelasan bagian-bagian kecil dari perintah besar tersebut
  • Jika perintah ini memiliki tujuan yang berbeda, lalu apa yang akan menjadi perintah yang benar untuk mencapai apa yang penulis klaim lakukan?

Saya menjadi sangat bingung dan frustrasi ketika saya mencoba menyimpulkan semuanya sendiri. Bagaimana perintah ini bekerja untuk itu berisi banyak /, |, \, *, dan ^karakter yang sulit untuk Google untuk.

Saya mencari terjemahan langkah demi langkah & penjelasan untuk perintah ini yang tidak dapat saya temukan di internet!

Bhavesh Diwan
sumber
1
Ini sepertinya bukan perintah yang sama dengan yang Anda kutip, tetapi saya telah menggunakan perintah di tuxtweaks.com/2010/10/… untuk menghapus kernel lama tanpa masalah. Halaman ini juga menjelaskan apa yang dilakukan perintah.
user68186
4
@UriHerrera apt-get autoremovetidak menyarankan penghapusan kernel yang lebih tua untuk saya. Jika saya tidak menghapusnya, mereka hanya akan menumpuk sampai saya /bootkehabisan ruang dan pembaruan gagal. Apakah Anda memiliki referensi untuk itu tentang hal yang seharusnya dilakukan?
gertvdijk
1
Itu berlaku untuk saya, setiap kali ada pembaruan baru untuk kernel, ia mengatakan setelah itu paket-paket berikut, dll, tidak lagi diperlukan dan mencantumkan kernel sebelumnya yang saya miliki.
Uri Herrera
Jawaban saya dihapus oleh moderator, jadi saya berkomentar di sini: Lihat artikel ini untuk penjelasan skrip. Saya tidak melihat mengapa satu bagian dari skrip s/^[^ ]* [^ ]* \([^ ]*\).*/\1/bukan hanya s/^[^ ]* \([^ ]*\).*/\1/. Scriptnya tidak terlalu kuat atau elegan. Sebagai contoh mengapa memeriksa kernel saat ini sebelum mengekstraksi nama paket dari output? Sebagai alternatif, sudo apt-get autoremove --purgehapus sebagian besar kernel lama di beberapa rilis terbaru Ubuntu seperti Xubuntu 15.10.
jarno

Jawaban:

27

Saya akan mengatakan: jangan menggunakannya dalam bentuk saat ini

  1. Itu membuat perubahan tanpa meminta Anda. Bagian ini apt-get -y purgememungkinkan one-liner untuk mulai menjalankan paket pembersihan, tanpa konfirmasi Anda. Jika ada kesalahan dalam skrip, maka Anda bisa kacau .

  2. Tidak ada sumber, tidak ada penulis yang diberikan. Sumbernya membuat perbedaan di sini. Jika itu datang dari paket sistem yang diuji secara menyeluruh, kami dapat melacak pengujian yang dilakukan terhadapnya. Dari sumber acak, kami tidak bisa mempercayainya.

  3. dpkg -lberjalan dengan baik tanpa sudo. Saya tidak mengerti mengapa penulis asli berpikir ini perlu.

Gunakan akal sehat

Buang bagian yang berbahaya dan tinggalkan apa pun yang berjalan sebagai root.

Misalnya, kurangi menjadi ini:

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

yang hanya menampilkan barang dan berjalan dengan izin pengguna biasa . Setelah Anda setuju dengan kernel ini untuk dihapus, Anda dapat menambahkan | xargs sudo apt-get purge sendiri. Tanpa -ypilihan, sengaja, jadi Anda akan diminta konfirmasi tentang perubahan yang akan dilakukan pada sistem Anda.

Penjelasan

  • dpkg -lKeluarkan daftar semua paket. Dalam hal ini hanya akan mencantumkan paket yang dimulai dengan linux-namanya.
  • |(sebuah pipa) menyalurkan output dari perintah di sebelah kiri (kami menyebutnya stdout) ke input dari perintah di sebelah kanan (kami menyebutnya stdin).
  • sedadalah alat untuk memanipulasi string menggunakan ekspresi reguler . Dalam hal ini memanipulasi output dari perintah di sebelah kiri pipa dan menyaring untuk paket yang diinstal (mengandalkan iiseperti yang diberikan oleh dpkg). Bahkan sedang bersarang dalam kasus ini. Akan terlalu sulit untuk menjelaskan keseluruhan penggunaan di sedsini, karena penggunaannya sangat rumit dengan ekspresi reguler yang kompleks. (Ini \(.*\)-\([^0-9]\+\)"adalah contoh dari ekspresi reguler.
  • Ekspresi reguler sangat banyak digunakan untuk menemukan kecocokan berdasarkan ekspresi yang diwakilinya. \1adalah referensi pengganti untuk melakukan semacam pencarian-dan-ganti universal (merujuk pada 'hit' pertama dengan 1). Ekspresi reguler itu sendiri tidak dapat membahayakan. Namun, jika mereka memanipulasi input dengan cara yang salah, mereka dapat meminta Anda menghapus paket yang salah atau bahkan melakukan injeksi shell. Dalam hal ini sepertinya cara untuk menemukan nama paket kernel berdasarkan versi yang disediakan oleh uname -r.
  • uname -r menampilkan versi saat ini dari kernel yang berjalan.
  • xargsmenambahkan baris input kiri pipa sebagai argumen untuk perintah. Dalam hal ini, versi kernel pada setiap baris dikonversi ke daftar yang dipisahkan oleh ruang secara horizontal dan ditambahkan ke sudo apt-getperintah.
  • sudo apt-get -y purge [packagename] pembersihan (menghapus semuanya) dari paket yang diberikan (sebagai argumen).

Alternatif

Beberapa pertanyaan mungkin sudah ditanyakan tentang ini. Yang relevan yang saya temukan sejauh ini:

gertvdijk
sumber
1
apa yang akan menjadi perpecahan dari node yang tampak menakutkan dari perintah ini yang kira-kira seperti ini /(.*)-([^0-9[\+)/\1/")"'/d;s/^[^ ] * [^] * ([^] *). * / \ 1 /; /
Bhavesh Diwan
akankah perintah di atas dalam jawaban ini membersihkan kernel lama dengan anggun ?? atau masih apt-get autoremove lebih baik ??
Bhavesh Diwan
4
@ Z9iT Itu adalah ekspresi reguler. Mereka terbiasa menemukan kecocokan berdasarkan ekspresi yang mereka wakili dan \1kontrol penggantian untuk melakukan semacam pencarian dan penggantian universal. Untuk menghapus paket apa pun saya telah menyatakan diri saya dengan jelas dalam jawaban saya (sebagai pendapat saya): gunakan akal sehat. Jangan biarkan skrip melakukan perubahan pada sistem Anda secara otomatis. Verifikasi apa yang akan dilakukan. Selalu.
gertvdijk
Alternatif yang Anda tampilkan tidak membersihkan paket linux-header masing-masing.
jarno
Kemudian lakukan autoremove apt-get, yang seharusnya mendeteksi header-header itu tidak lagi diperlukan.
ben-Nabiy Derush
7

Anda meminta penjelasan langkah demi langkah jadi begini:

sudo dpkg -l 'linux-*'

Daftar paket yang dimulai dengan linux-nama paket

| sed

dan pipa daftar ke sed

"s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'

yang akan menggunakan ekspresi reguler yang sangat rumit untuk mengedit daftar

| xargs

yang akan menyalurkan daftar baru ke xargs, yang akan mengirimkannya sebagai argumen untuk

sudo apt-get -y purge

yang akan membersihkan paket-paket itu tanpa memberi Anda kesempatan untuk berubah pikiran.

Atau mungkin lebih akurat untuk mengatakan itu akan mengirim daftar itu ke perintah pembersihan dan biarkan begitu saja. Apakah sesuatu dibersihkan atau tidak - persis apa yang dibersihkan tergantung pada ouput dari perintah sebelumnya.

Apakah ini aman? Dalam hal ini semua tergantung pada seberapa baik penulis posting di mana Anda menemukannya memahami ekspresi reguler dan sedsintaksis. Dan ada banyak buku tentang kedua topik itu.

chaskes
sumber
6

Saya mulai dengan membedah perintah, membaca manhalaman untuk masing-masing.

  • dpkg -l: daftar pacakges, jadi dpkg -l linux-*akan mencantumkan semua paket yang dimulai dengan linux-(biasanya kernel).

  • sed: Output dari dpkg -l linux-*disalurkan ke seddengan beberapa ekspresi reguler yang sedmenerjemahkan.

  • uname -r unamemencetak informasi sistem

uname - print system information

The -rmenangani secara khusus mencetak rilis kernel:

-r, --kernel-release cetak rilis kernel

Output dari uname -rkemudian disalurkan ke seddengan ekspresi yang lebih teratur, yang outputnya diteruskanxargs

Jadi, xargsterjemahkan sedoutput ke dalam nama paket dan berikan ke sudo apt-get purge -yyang secara otomatis menjawab 'ya' untuk semua konfirmasi:

-y, --ya, --assume-ya Otomatis ya untuk meminta; anggap "ya" sebagai jawaban untuk semua pertanyaan dan jalankan secara non-interaktif. Jika situasi yang tidak diinginkan, seperti mengubah paket yang ditahan, mencoba menginstal paket yang tidak diautentikasi atau menghapus paket penting terjadi maka apt-get akan dibatalkan. Item Konfigurasi: APT :: Get :: Asumsikan-Ya.

Secara keseluruhan sepertinya perintah ini akan melakukan apa yang Anda inginkan, meskipun untuk mengetahui dengan pasti kita harus menerjemahkan sedekspresi reguler.

Saya hanya berlari:

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

di sini adalah tangkapan layar:

masukkan deskripsi gambar di sini

Semua versi kernel lama iirc.

Seth
sumber
apa latihan untuk menerjemahkan ekspresi sed ini?
Bhavesh Diwan
2
Saya mencoba memahaminya sekarang, mungkin perlu waktu;)
Seth
Lihat jawaban saya .
jarno
@ Z9iT Saya terlalu malas untuk menyalin penjelasan skrip dari artikel yang ditautkan ke jawabannya, jadi saya kira itu sebabnya Seth menghapus jawaban saya. Tapi saya pikir artikel tertaut adalah apa yang Anda cari dari Internet. Saya juga memberi tahu Anda cara yang lebih aman untuk menghapus kernel lama, meskipun kernel itu menyimpan 2-3 kernel untuk berjaga-jaga, dan mungkin belum bekerja di semua rilis Ubuntu saat ini.
jarno
@ Jarno Saya menghapusnya karena Z9iT menanyakan tentang perintah tertentu , bukan cara yang aman untuk menghapus kernel lama. Itu mungkin masih relevan, tetapi dalam komentar, bukan jawaban :) (seperti yang Anda lakukan)
Seth