O que essa instrução 'apt-get remove' faz?

10

O que o código a seguir faz?

Eu encontrei na internet, então eu copiei e colei no terminal, mas quando eu instalei um novo kernel, ele detecta apenas o antigo.

sudo apt-get remove --purge $(dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)//")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*//;/[0-9]/!d')
    
por medo_alouane 16.04.2015 / 20:44

2 respostas

12

Vamos quebrar o código um por um (para o meu 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]\+\)//'
3.13.0-32



$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)//')/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]\+\)//')/d" | sed 's/^[^ ]* [^ ]* \([^ ]*\).*//'
linux-image-generic



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

Então, isso não faria nada:

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

Como você pode ver, estava muito perto de remover meu meta pacote atual do kernel linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image (graças a esta última sed '/[0-9]/!d' line), o que está errado.

Em suma, este artigo de sed tem vários problemas. Você deve evitá-lo para remover seus kernels mais antigos.

EDITAR:

Eu já disse que o comando sed tem problemas. Por uma questão de extensão eu vou remover as duas últimas linhas com o formulário que realmente deveria estar funcionando no meu cenário atual.

As últimas duas linhas de uma forma modificada:

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

Então:

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

Outpus:

linux-image-3.13.0.32-generic

Isso é muito perigoso !!

Agora mostrando o que isso faria no meu sistema, --dry-run do comando apt-get remove completo:

$ sudo apt-get remove --dry-run $(dpkg -l 'linux-image-*' | 
sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)//")"'/d' | 
sed -r 's/^[^ ]* *(([a-z]|-)*)(-[a-z]*) *(([0-9]|\.|-)*)\..*/\-/')


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]

Como você vê, ele removerá todos os meus kernels atuais, também observe que isso é apenas uma simulação para corresponder ao meu cenário atual e que o original sed pode ser melhorado.

** Observe que o código real funcionará se um reboot após a atualização do kernel for Oli já mencionado .

EDIT2:

Aqui está um script simples, mas robusto, que considerará todas as situações e removerá os kernels mais antigos:

#!/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 você tiver alguma versão mais recente que a atual, isso lhe dará um aviso para reiniciar o computador primeiro. Note também que os kernels mais antigos são preservados devido a uma boa razão que é se você de alguma forma atrapalhar seu kernel atual tornando seu sistema instável, então você deve ser capaz de inicializar em qualquer kernel antigo.

    
por heemayl 16.04.2015 / 21:09
12

Este é um esforço para remover os kernels que não são os atuais.

Existem muitos pedaços de código que fazem algo assim e não é um bom exemplo . Ele poderia facilmente remover os kernels mais recentes que o atual e, portanto, o meta-pacote que é instalado ( linux-generic et al) se você tivesse uma atualização e não reinicializasse.

    
por Oli 16.04.2015 / 21:09