古いカーネルを削除するこのコマンドは安全に使用できますか?


21

Ubuntuの記事をインターネットで閲覧しているときに、次のコマンドに出会いました。

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

著者は、これはLinuxの以前のバージョンをすべて削除し、現在のバージョンのみを残す単一行コマンドであると述べました

私は実際にそのようなコマンドを探していますが、これがどれほど安全かはわかりません。知りたい:

  • このコマンドを実行しても安全かどうか
  • このコマンドはどのように機能しますか?すなわち、そのような大きなコマンドの小さな部分の説明
  • このコマンドがいくつかの異なる目的に役立つ場合、著者がそれを行うと主張することを達成するための正しいコマンドは何でしょうか?

自分ですべてを推測しようとすると、非常に混乱してイライラします。どのようにこのコマンドの仕事、それが含まれているため、多くの/|\*、および^のためにGoogleにハードな文字。

私はインターネットで見つけることができなかったこのコマンドのステップバイステップの翻訳と説明を探しています!


1
これは、引用したコマンドと同じではないようですが、問題なく古いカーネルを削除するためにtuxtweaks.com/2010/10/…のコマンドを使用しています。このページでは、コマンドの機能についても説明しています。
-user68186

4
@UriHerrera apt-get autoremoveは古いカーネルの削除を提案しません。それらを削除しない/bootと、スペースが不足して更新が失敗するまで、それらは積み上げられます。これを行うべきであるということについての参照はありますか?
gertvdijk

1
私にとっては、カーネルの新しい更新があるたびに、その後、次のパッケージなどは不要になり、以前持っていたカーネルが一覧表示されます。
ウリエレーラ

私の回答はモデレーターによって削除されたため、ここでコメントします。スクリプトの説明については、この記事を参照してください。スクリプトの一部s/^[^ ]* [^ ]* \([^ ]*\).*/\1/が単純ではなくなぜかわかりませんs/^[^ ]* \([^ ]*\).*/\1/。スクリプトは非常に堅牢でもエレガントでもありません。たとえば、出力からパッケージ名を抽出する前に現在のカーネルを確認する理由は何ですか?別の方法として、sudo apt-get autoremove --purgeXubuntu 15.10のようなUbuntuの最新リリースのほとんどの古いカーネルを削除します。
jarno

回答:


27

私は言うだろう:現在のフォームで使用しないでください

  1. それはあなたに尋ねることなく変更を行います。このapt-get -y purge部分により、ワンライナーは確認なしでパージパッケージの実行を開始できます。スクリプトにエラーが存在する場合は、ねじ込まれている可能性があります。

  2. ソースも著者も指定されていません。そのソースはここで違いを生みます。徹底的にテストされたシステムパッケージに由来する場合は、実行されているテストを追跡できます。ランダムなソースから、それを信頼することはできません。

  3. dpkg -lなしで正常に実行されますsudo。元の著者がこれが必要だと思った理由がわかりません。

常識を使う

有害な部分を削除し、ルートとして実行されるものはすべて除外します。

たとえば、次のように切り詰めます。

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

ただのもの出力し、通常のユーザー権限で実行します。これらのカーネルを削除することに同意したら、自分で追加 できます| xargs sudo apt-get purge-y意図的にオプションがないため、システムに加えられる変更について確認を求められます。

説明

  • dpkg -lすべてのパッケージのリストを出力します。このケースでは、パッケージのみが一覧表示されます開始linux-名前として。
  • |(パイプ)は、左側のコマンドの出力(これをstdout)と呼び、右側のコマンドの入力(それを)とパイプしますstdin
  • sed正規表現を使用して文字列を操作するツールです。この場合、パイプの左側のコマンドの出力を操作し、インストールされたパッケージのフィルターを適用します(でii指定されたものに依存しますdpkg)。この場合はネストされています。sed複雑な正規表現では使用が非常に複雑であるため、ここでの使用全体を説明するのは非常に困難です。(これ\(.*\)-\([^0-9]\+\)"は正規表現の例です。
  • 正規表現は、それらが表す表現に基づいて一致を見つけるために非常に広く使用されています。\1は、ある種の汎用的な検索と置換を行うための置換参照です(最初の「ヒット」を1参照)。正規表現自体は害を及ぼしません。ただし、入力を誤った方法で操作すると、間違ったパッケージを削除したり、シェルインジェクションを実行したりする可能性があります。この場合、によって提供されるバージョンに基づいてカーネルパッケージの名前を見つける方法のように見えますuname -r
  • uname -r 実行中のカーネルの現在のバージョンを出力します。
  • xargsコマンドへの引数として、パイプの左側の入力の行を追加します。この場合、各行のカーネルバージョンは、スペースで区切られた水平方向のリストに変換され、sudo apt-getコマンドに追加されます。
  • sudo apt-get -y purge [packagename] (引数として)指定されたパッケージをパージ(すべて削除)します。

代替案

このことについては、おそらくかなりの質問がすでに聞かれているでしょう。これまでに見つけた関連するもの:


1
このコマンドの恐ろしい見た目のノードは、次のようになります/(.*)-([^0-9]\+)/\1/")"'/d;s/^[^ ] * [^] *([^] *)* / \ 1 /、/。
Bhaveshディワン

この回答の上記のコマンドは、古いカーネルを正常にクリアしますか?またはまだapt-get autoremoveの方が良いですか??
バベシュディワン

4
@ Z9iTこれらは正規表現です。それらは、表現する表現に基づいて一致を見つけるために使用され、これ\1は一種の汎用的な検索と置換を実行するための置換コントロールです。パッケージを削除するために、私は自分の答えで自分の意見を明確に表明しました。スクリプトがシステムに自動的に変更を加えないようにしてください。それが何をするかを確認してください。常に。
gertvdijk

代替機能は、それぞれのlinux-headerパッケージをパージしません。
jarno

次に、apt-get autoremoveを実行するだけで、これらのヘッダーが不要になったことを検出できます。
ベンナビイデラッシュ

7

あなたはステップバイステップの説明を求めたので、ここに行きます:

sudo dpkg -l 'linux-*'

linux-パッケージ名で始まるパッケージのリスト

| sed

リストをパイプして sed

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

非常に複雑な正規表現を使用してリストを編集します

| xargs

これにより、新しいリストがにパイプさxargsれ、引数としてリストが送信されます。

sudo apt-get -y purge

気が変わる機会を与えずにこれらのパッケージを削除します。

または、そのリストをパージコマンドに送信し、そのままにしておくと言う方が正確かもしれません。何かがパージされるかどうか-そして重要なこと- パージされるものかは、前のコマンドの出力に依存します。

安全ですか?この場合、すべては、あなたが見つけた投稿の著者が正規表現とsed構文をどれだけ理解しているかに依存します。そして、これらのトピックの両方に関する本全体があります。


6

まず、コマンドを分析し、manそれぞれのページを読み始めました。

  • dpkg -l:リストpacakgesは、そうdpkg -l linux-*で開始されたすべてのパッケージ一覧表示しますlinux-(通常はカーネルを)。

  • sed:の出力は、デコードするいくつかの正規表現でdpkg -l linux-*パイプさsedsedます。

  • uname -r unameシステム情報を出力します

uname-システム情報を出力します

-rハンドルは、特にカーネルのリリースを出力します。

-r、-kernel-releaseカーネルリリースを出力します

の出力は、さらに正規表現でuname -rパイプさsedれ、その出力はxargs

そのxargsため、sed出力をパッケージ名に変換し、sudo apt-get purge -yすべてのプロンプトに対して自動的に「yes」と応答するパッケージ名に渡します。

-y、-yes、-assume-yesプロンプトに対する自動yes; すべてのプロンプトに対する答えとして「はい」を想定し、非対話的に実行します。保留パッケージの変更、認証されていないパッケージのインストール、または重要なパッケージの削除などの望ましくない状況が発生した場合、apt-getは中止されます。構成アイテム:APT :: Get :: Assume-Yes。

要するに、このコマンドはそうだろう、我々は変換する必要があると思います確かに知っているけれども、あなたがやりたいですsedの正規表現ます。

私はちょうど走った:

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

これがスクリーンショットです:

ここに画像の説明を入力してください

すべての古いカーネルバージョンiirc。


このsedの表現を翻訳するためのトレーニングは何ですか?
バベシュディワン

2
私は今それを理解しようとしています、しばらく時間がかかるかもしれません;)
セス

私の答えをご覧ください。
ジャーノ

@ Z9iTリンクされた記事のスクリプトの説明を回答にコピーするのが面倒だったので、セスが回答を削除したのはそのためだと思います。しかし、リンクされた記事はあなたがインターネットから探していたものだと思います。古いカーネルを削除するより安全な方法もお伝えしましたが、念のため2〜3個のカーネルを保持しており、現在のすべてのUbuntuリリースではまだ動作しない可能性があります。
jarno

@jarno Z9iTが特定のコマンドについて尋ねていたので削除しました。古いカーネルを安全に削除する方法ではありません。それはまだ関連しているかもしれませんが、コメントではなく、答えで:)(あなたがしたように)
セス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.