この「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')

2番目の部分は正規表現であり、ファイル名がどのように見えるかを定義しますが、正確にはどのファイル名であるかを定義しません。それはあなたの目的であるカーネルをインストールしていますか、それともコマンドが削除したものを正確に見つけていますか?
Niklas Lindskog

このコードはカーネルをインストールしませそれらを削除します!このsed-commandが正確に何をしているのかはわかりませんが、dpkg -l 'linux-image-*'インストールされているすべてのカーネルパッケージを一覧表示し、それらの一部をによって削除するためにフィルターで除外するの出力を処理します apt-get remove
バイトコマンダー

16
経験則としては、コードの機能がわからない場合は、そのコードを知っている人から指示があるまで、そのコードをターミナルに挿入しないでください。最新のカーネルを取得しようとしている場合は、理解できないコードを使用する代わりに、askubuntu.com / questions / 119080 /…を参照することをお勧めします。
Trogdor大佐2015

ディスク上にある古いカーネルは、ディスク領域を占有し、update-grub(パッケージのポストインスト)を遅くすることを除いて、問題を引き起こしません。アップグレードしようとしているカーネルを実際に起動しなかったのではないかと心配している場合は、を実行するuname -aか、さらにはdmesg | less
Peter Cordes

7
「インターネットで見つけたので、コピーしてターミナルに貼り付けました」NO NO NO NO NO。あなたは偶然に恐ろしいことをすることになります。理解していないコードを実行すると、システムが無力になったり、子犬が蹴られたりするなど、恐ろしい事態が発生します。
ジャーニーマンオタク

回答:


12

(私のシステムでは)コードを1つずつ壊してみましょう。

$ 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コマンドには問題があるとすでに述べました。拡張のために、現在のシナリオで実際に機能するはずのフォームの最後の2行を削除します。

変更された形式の最後の2行:

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

Outpus:

linux-image-3.13.0.32-generic

それは非常に危険です!!

これが私のシステムに何をするかを示し--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されます。これは現在のシナリオに一致するシミュレーションにすぎず、オリジナルを改善できることにも注意してください。

** Oliが既に述べたようにreboot、カーネルのアップグレード後に実際のコードが機能することに注意してください。

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。
Ilmari Karonen

オリの回答などで指摘されているように、元のコードを批判する正当な理由は確かにあり、sedコードをより堅牢にすることができると私は確信しています。ただし、通常の状況(最後のカーネルアップグレード後に再起動した場合など)では元のコードは機能しますが、変更したバージョンでは機能しないという事実は変わりません。
Ilmari Karonen

1
まず、使用した最後の単語は使用しないでください。実際に、実際のコードを実行しましたか?apt-get部品を取り外して、どのような出力を得ましたか?
heemayl 2015

@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つしかありません。
Barafu Albino、2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.