Що робить ця інструкція "apt-get remove"?


10

Що робить наступний код?

Я знайшов його в Інтернеті, тому скопіював його і вставив у термінал, але коли я встановив нове ядро, він виявляє лише старе.

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

Друга частина - це регулярний вираз, який визначає, як має виглядати ім'я файлу, але не точно, яке саме ім'я файлу. Це встановлення ядра, яке є вашою метою, або це з'ясування того, що команда видаляє?
Ніклас Ліндського

Цей код не встановить жодне ядро, але видалить їх! Я не бачу, що саме робить ця команда sed, але вона обробляє вихід dpkg -l 'linux-image-*', який перераховує всі встановлені пакети ядра і фільтрує деякі з них для видалення apt-get remove.
Байт-командир

16
Дуже хороше правило, яким потрібно жити: якщо ви не знаєте, що робить код, не вкладайте цей код у термінал, поки не скаже вам хтось, хто знає, що він робить. Якщо ви намагаєтеся отримати найновіше ядро, ви можете подивитися на askubuntu.com/questions/119080/… замість того, щоб використовувати код, який ви не розумієте.
Полковник Трогдор

Старі ядра, що сидять навколо диска, не створюють ніяких проблем, за винятком того, що займає місце на диску та робить update-grubповільніше (пакетний поштовий пакет). Якщо ви переживаєте, що ви насправді не завантажили ядро, на яке ви намагалися оновити, а потім запустіть uname -aабо навітьdmesg | less
Пітер Кордес

7
"Я знайшов його в Інтернеті, тому скопіював його і вставив у термінал" NO NO NO NO NO. Ви випадково зробите жахливі речі. Якщо ви працюєте з кодом, ви не розумієте результатів у страшних речах, таких як забивання вашої системи, а щенят виганяють.
Подорож Гек

Відповіді:


12

Розбимо код по черзі (для моєї системи):

$ 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

Отже, це нічого не зробить:

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

Як ви бачите, це було дуже близько до видалення мого поточного мета-пакету ядра linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image (завдяки цьому останньому sed '/[0-9]/!d'рядку), що неправильно.

Якщо коротко, цей твір sedмає кілька питань. Вам слід уникати цього, щоб видалити старіші ядра.

Редагувати:

Я вже казав, що у sedкоманди є проблеми. Заради розширення я збираюся видалити останні два рядки з форми, яка насправді повинна працювати в моєму поточному сценарії.

Останні два рядки в модифікованому вигляді:

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

Тому:

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

Вихід:

linux-image-3.13.0.32-generic

Thats дуже небезпечний !!

Тепер показую, що це зробить для моєї системи, --dry-runзазначаючи повну apt-get removeкоманду:

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

Як ви бачите, що це видалить усі мої поточні ядра, також зауважте, що це лише симуляція, що відповідає моєму поточному сценарію, і оригінал sedможе бути вдосконалений.

** Зауважте, що фактичний код буде працювати, якщо зробити rebootпісля оновлення ядра, як уже згадував Oli .

EDIT2:

Ось простий, але надійний сценарій, який буде враховувати всі ситуації та видаляти фактичні старі ядра:

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

Якщо у вас є будь-яка версія, яка є новішою, ніж поточна, то це попередить спочатку перезавантажити комп'ютер. Також зауважте, що старіші ядра зберігаються через вагому причину, яка полягає в тому, що якщо ви якимось чином псуєте своє поточне ядро, роблячи вашу систему нестабільною, то ви повинні мати можливість завантажуватися в будь-яке старе ядро.


Гм, почекай, що? Ви замінюєте оригінальний, робочий код на якийсь інший код, який, на вашу думку, "насправді повинен (!!) бути там", зауважуєте, що ваш "виправлений" код зламаний і видалить ваше поточне ядро, і таким чином зробите висновок, що вихідний код є " дуже небезпечно !! "? WTF? -1.
Ільмарі Каронен

Безумовно, є вагомі причини критикувати оригінальний код, на що вказувалось, наприклад, у відповіді Олі, і я впевнений, що код Sed може бути більш надійним. Але цей факт залишається тим, що за звичайних обставин (наприклад, ви перезавантажилися після останнього оновлення ядра), оригінальний код працює, тоді як ваша змінена версія не працює.
Ільмарі Каронен

1
Перш за все, ви не повинні вживати останнє слово, яке ви вживали. Тепер ви справді запустили фактичний код? видалення apt-getдеталі та який результат ви отримали?
heemayl

@IlmariKaronen: Ну, я другий з вами в деяких моментах, я змінив відповідь ..
heemayl

Чому, так, я ж запустити змінену команду (версію , яка не врізатися з - за відсутні дужки після (([a-z]|-)*, тобто) без apt-getчастини , перш ніж критикувати його. У моїй системі, він виводить наступні рядки: 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. Це дійсно те, що ви задумали? (Також бонусні бали, якщо ви можете зрозуміти, які ядра я фактично встановив.)
Ilmari Karonen

12

Це намагання видалити ядра, які не є поточними.

Існує багато бітів коду, які роблять щось подібне, і це не гарний приклад . Він міг би легко видалити новіші, ніж поточні ядра, а тому метапакет, який встановлюється ( linux-genericта ін.), Якщо ви мали оновлення та не перезавантажувались.


2
І це зовсім не гарна ідея. Ці старі ядра зберігаються з причини, за замовчуванням є лише 2 старі та поточні.
Барафу Альбіно
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.