Cosa fa questa istruzione 'apt-get remove'?


10

Cosa fa il seguente codice?

L'ho trovato su Internet, quindi l'ho copiato e incollato nel terminale, ma quando ho installato un nuovo kernel rileva solo quello vecchio.

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

La seconda parte è un'espressione regolare, che definisce l'aspetto del nome del file ma non esattamente il nome del file. Sta installando un kernel che è il tuo obiettivo o sta scoprendo esattamente cosa rimuove il comando?
Niklas Lindskog,

Questo codice non installa alcun kernel, ma li rimuove ! Non vedo esattamente cosa fa questo comando sed, ma elabora l'output di dpkg -l 'linux-image-*', che elenca tutti i pacchetti del kernel installati e ne filtra alcuni per eliminarli apt-get remove.
Byte Commander

16
Una regola empirica molto buona da rispettare: se non sai cosa fa un codice, non metterlo nel Terminale fino a quando qualcuno che sa cosa ti dice. Se stai cercando di ottenere il kernel più aggiornato, potresti voler consultare askubuntu.com/questions/119080/… invece di usare un codice che non capisci.
Colonnello Trogdor,

I vecchi kernel che si trovano sul disco non causano problemi, tranne che per occupare spazio su disco e rendere update-grub(pacchetto postinst) più lento. Se sei preoccupato di non aver effettivamente avviato il kernel a cui stavi tentando di aggiornare, quindi eseguire uname -ao addiritturadmesg | less
Peter Cordes,

7
"L'ho trovato su Internet, quindi l'ho copiato e incollato nel terminale" NO NO NO NO NO. Finirai per fare cose orribili per caso. L'esecuzione di un codice che non capisci provoca cose terribili come la distruzione del sistema e la caccia ai cuccioli.
Journeyman Geek,

Risposte:


12

Rompiamo il codice uno per uno (per il mio sistema):

$ 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

Quindi questo non farebbe nulla:

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

Come puoi vedere è stato molto vicino alla rimozione del mio attuale meta pacchetto del kernel linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image (grazie a quest'ultima sed '/[0-9]/!d'riga), il che è sbagliato.

In breve, questo pezzo sedha diversi problemi. Dovresti evitarlo per rimuovere i tuoi kernel più vecchi.

MODIFICARE:

Ho già detto che il sedcomando ha dei problemi. Per motivi di estensione, rimuoverò le ultime due righe con il modulo che in realtà dovrebbe funzionare nel mio scenario attuale.

Le ultime due righe in una forma modificata:

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

Così:

$ 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

Questo è molto pericoloso !!

Ora mostrando cosa farebbe al mio sistema, --dry-runeseguendo il apt-get removecomando completo :

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

Come vedi rimuoverà tutti i miei kernel attuali, nota anche che questa è solo una simulazione per abbinare il mio scenario attuale e l'originale sedpuò essere migliorato.

** Nota che il codice effettivo funzionerà se esegui un rebootaggiornamento del kernel dopo che Oli ha già menzionato .

EDIT2:

Ecco uno script semplice ma robusto che prenderà in considerazione tutte le situazioni e rimuoverà i kernel più vecchi:

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

Se si dispone di una versione più recente di quella corrente, verrà visualizzato un avviso per riavviare prima il computer. Si noti inoltre che i kernel più vecchi sono conservati a causa di una buona ragione che è se in qualche modo si confonde il kernel corrente rendendo il sistema instabile, quindi si dovrebbe essere in grado di avviare qualsiasi kernel più vecchio.


Aspetta, cosa? Sostituisci il codice originale funzionante con qualche altro codice che pensi "effettivamente dovrebbe (!!) essere lì", osserva che il tuo codice "riparato" è rotto e rimuove il tuo kernel corrente, e quindi concludi che il codice originale è " molto dengerous !! "? WTF? -1.
Ilmari Karonen,

Esistono certamente validi motivi per criticare il codice originale, come sottolineato ad esempio nella risposta di Oli, e sono sicuro che il codice sed potrebbe essere reso più robusto. Ma questo fatto rimane che, in circostanze normali (ad esempio, dopo il riavvio dell'ultimo aggiornamento del kernel), il codice originale funziona, mentre la versione modificata non funziona.
Ilmari Karonen,

1
Prima di tutto non dovresti usare l'ultima parola che hai usato ... sai, hai effettivamente eseguito il codice attuale? rimuovere la apt-getparte e quale output hai ottenuto?
heemayl

@IlmariKaronen: beh, sono seconda con te in alcuni punti, ho modificato la risposta ..
heemayl

Perché, sì, ho fatto eseguire il comando modificato (la versione che non va in crash a causa di una parentesi dispersi dopo (([a-z]|-)*, che è) senza la apt-getparte prima di criticarlo. Sul mio sistema, emette le seguenti righe: 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. È davvero quello che volevi? (Inoltre, punti bonus se riesci a capire quali kernel ho effettivamente installato.)
Ilmari Karonen

12

Questo è uno sforzo per rimuovere i kernel che non sono quelli attuali.

Ci sono molti bit di codice là fuori che fanno qualcosa del genere e questo non è un buon esempio . Potrebbe rimuovere facilmente i kernel più recenti dell'attuale e quindi il meta-pacchetto che installa ( linux-genericet al) se hai avuto un aggiornamento e non hai riavviato.


2
E questa non è affatto una buona idea. Quei kernel più vecchi sono mantenuti per la ragione, di default ce ne sono solo 2 vecchi e uno attuale.
Barafu Albino,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.