インストール日ごとにaptベースのシステム上のパッケージを一覧表示する


104

インストールされたパッケージをインストール日ごとに一覧表示するにはどうすればよいですか?

debian / ubuntuでこれを行う必要があります。他のディストリビューションへの回答もいいでしょう。

特定のコードをコンパイルするために多くのものをインストールしましたが、インストールする必要があるパッケージのリストを取得したいと思います。


1
apt-get installの履歴を取得する方法も参照してください。
ミケル

1
幸運にも "aptリリース日"を探していましたが、このコメントが将来のGoogleユーザーに役立つかもしれません。
ThorSummoner 14年

回答:


66

Red HatのようなRPMベースの配布は簡単です。

rpm -qa --last

Debianや他のdpkgベースのディストリビューションでは、特定の問題も簡単です。

grep install /var/log/dpkg.log

ログファイルがローテーションされていない限り、その場合は次のことを試してください。

grep install /var/log/dpkg.log /var/log/dpkg.log.1

一般的に、dpkgそしてapt中にそのような場の不足によって起こって、インストール日を追跡していないようですdpkg-queryマニュアルページを参照してください。

そして、最終的に古い/var/log/dpkg.log.*ファイルはログのローテーションによって削除されるため、その方法はシステムの全履歴を保証するものではありません。

数回表示される提案(このスレッドなど)は、/var/lib/dpkg/infoディレクトリを確認することです。そこにあるファイルは、次のようなことを試みることを示唆しています。

ls -t /var/lib/dpkg/info/*.list | sed -e 's/\.list$//' | head -n 50

選択についての質問に答えるために、ここに最初のパスがあります。

日付ごとにパッケージのリストを作成する

$ find /var/lib/dpkg/info -name "*.list" -exec stat -c $'%n\t%y' {} \; | \
    sed -e 's,/var/lib/dpkg/info/,,' -e 's,\.list\t,\t,' | \
    sort > ~/dpkglist.dates

インストール済みパッケージのビルドリスト

$ dpkg --get-selections | sed -ne '/\tinstall$/{s/[[:space:]].*//;p}' | \
    sort > ~/dpkglist.selections

2つのリストに参加する

$ join -1 1 -2 1 -t $'\t' ~/dpkglist.selections ~/dpkglist.dates \
    > ~/dpkglist.selectiondates

なんらかの理由で、私にはあまり多くの違いが出力されないので、何が--get-selections意味するのかについてバグや無効な仮定があるかもしれません。

find . -mtime -<days>またはを使用してパッケージを制限し、必要に応じhead -n <lines>て出力形式を変更できます。たとえば、

$ find /var/lib/dpkg/info -name "*.list" -mtime -4 | \
    sed -e 's,/var/lib/dpkg/info/,,' -e 's,\.list$,,' | \
    sort > ~/dpkglist.recent

$ join -1 1 -2 1 -t $'\t' ~/dpkglist.selections ~/dpkglist.recent \
    > ~/dpkglist.recentselections

過去4日間にインストールされた(変更された?)選択項目のみをリストします。

また、sort使用されるソート順を確認した後にコマンドを削除しdpkg --get-selectionsfindコマンドをより効率的にすることもできます。


8
私は通常、apt-get以上のものrpmが好きですが、データベースにインストール日を保存しないため、debianは-1を取得します。debianのトリックには、選択したパッケージだけでなく、インストールされているすべてのパッケージが含まれていますが、良いスタートです。
エラザールレイボヴィッチ

Debianのためにあなたがそれほど嫌なもの(削除され得るhalf-installeduが行う場合のエントリを):grep install\ /var/log/dpkg.log
Pierz

@Mikel-すばらしい答え。'gather /var/lib/dpkg/info/*.list file info'を拡張し、「トップレベルパッケージ」(他のatpパッケージが依存しないatpパッケージ)以外をすべて除外するコードを追加しました。< askubuntu.com/a/948532/723997 > 投稿は、「手動で実行したapt-getインストールコマンドの履歴を表示するにはどうすればよいですか?」という質問に答えます
クレイグヒックス

1
Debian / Ubuntu:grep " install " /var/log/dpkg.log「ステータス」行も表示せず、「インストール」行のみをリストします。
デザート

aptもdpkgもdatetimeのインストール/変更を保存しない場合、2019年にそれはかなり受け入れられないように思われます。ログファイルをgrepすることに依存しています。これはどうですか?
theferrit32

20

Mikelはdpkgレベルでこれを行う方法を示しました。特に、/var/lib/dpkg/info/$packagename.listパッケージのインストール時に作成されます(その後は変更されません)。

APTツールを使用した場合(おそらく自動インストールと手動インストールのパッケージを懸念しているため、これを行ったと思われます)、に履歴があり/var/log/apt/history.logます。回転していない限り、すべてのAPTのインストール、アップグレード、および削除を追跡し、自動的にインストールされたとマークされたパッケージの注釈を付けます。これはかなり最近の機能で、APT 0.7.26で導入されたため、Debianではsqueezeで登場しました。Ubuntuでは、10.04にはありますhistory.logが、自動インストールされたアノテーションは10.10まで存在しません。


1
Mikelが指摘したように:「そして最終的に古い/var/log/dpkg.log.*ファイルはログローテーションによって削除されるので、その方法はシステムの全履歴を保証するものではありません。」現在の最上位パッケージ(他のパッケージが依存しないパッケージを意味する)を検出する方法については、この< askubuntu.com/a/948532/723997 >の回答を参照してください
Craig Hicks

5

ラフですが、動作します:

for fillo in `ls -tr /var/lib/dpkg/info/*.list` ; 
    do basename ${fillo} | sed 's/.list$//g' ; 
done > forens.txt

ls -ltr /var/lib/dpkg/info/*.list > forentime.txt

for lint in `cat forens.txt` ; do 
    echo -n "[ ${lint} Installed ] : " ; 
    echo -n "`grep /${lint}.list forentime.txt | awk '{ print $6, $7, $8 }'` : " ; 
    ( ( grep -A3 " ${lint}$" /var/lib/apt/extended_states | \
        grep '^Auto' > /dev/null ) && echo "Auto" ) || echo "Manual" ; 
done > pkgdatetime.txt

2
ブー、からの出力を解析するヒスls。これが危険である/本質的にバグがある理由に関するメモについては、mywiki.wooledge.org / ParsingLsを参照してください。より安全なオプションは、どちらfind -printfstat --formatを使用するか、明確に解析できるストリームを生成することです。
チャールズダフィー

@CharlesDuffy素敵なリンクですが、簡単にするために、使用ls -al --time-style=long-isoすると便利です。さらに、誰かがAPTパッケージの名前に名前を付けることはおそらく聞いたことがないでしょう\n\t\r\v
not2qubit

4

この/var/log/apt/history.logファイルは、扱いにくい形式のIMHOです。

開始日:{日付} {時間}コマンドライン:{コマンド} {オプション...}インストール:{パッケージ(バージョン)}、...、{パッケージ(バージョン)}、...終了日:{日付} {時間}

もっとログファイル形式のレコードを好むだろう

{日付} {時間} {タブ} {パッケージ} {タブ} {バージョン} {タブ} {コマンド} {オプション} \ n

または{package}だけでなく{dependencies}を示すXML。

現在実装されているように、探している情報を発見することはできますが、詳細を抽出するにはフォレンジック処理が必要です。


3

これはDebianシステムで動作します。ファイル形式は2011年以降に変更されたと思います。このシステムはかなり新しいので、古いシステムで動作するとは思わないでしょうが、ログを解凍してそれらすべてを参照するグロブ。

grep 'install ' /var/log/dpkg.log.1 | sort | cut -f1,2,4 -d' '

ファイルの各行の最初の2つのフィールド/var/log/dpkg.logは、日付と時刻です。grep部分のインストールの末尾のスペースに注意してください。これは、アップグレードによってインストールがトリガーされる可能性があるためです。


1
まさに私がすること。簡単です。ただし、zgrepを使用すると、すべての.gzログがzgrep 'install' /var/log/dpkg.log*のように検索されます。これらの厄介な「ハーフインストール」を防ぐために、「インストール」という単語の前にスペースを置きます。パッケージ名フィールドを取得するには、cut -f1,5を使用する必要がありました。もちろん、最終的には古いログは回転します。
geoO

2

誰もが望み、必要としているワンライナーは次のとおりです。

for x in $(ls -1t /var/log/dpkg.log*); do zcat -f $x |tac |grep -e " install " -e " upgrade "; done |awk -F ":a" '{print $1 " :a" $2}' |column -t

結果には、すべての(新しく)インストールおよびアップグレードされたパッケージが時系列で表示されます。

回線の説明:

  • ls -1t-すべてのdpkg.log*ファイル名を時系列順に取得します
  • zcat -f- IFファイルがあるのはgzipタイプそして、それを解凍ELSEだけでコンテンツを渡します。
  • tac-の出力反転猫をライン・バイ・ラインは、我々は正しい年代順の取得を確実にするために、。
  • grep- インストールまたはアップグレードされたパッケージのみを確認します。
  • awk -F ':a'- アーキテクチャフィールドをパッケージ名から分離します
  • column -t -スペースで区切られた列をきれいに印刷します

もちろん、このエイリアスを作成したいと思いますが、残念ながらawkは一重引用符と二重引用符の両方に依存しているため、それはできません。その点で、これはbashスクリプトに配置するのが最適であり、フィールド列の:他のアーキテクチャではセパレータがより適切に処理されます。

出力は次のとおりです。

2018-03-06  18:09:47  upgrade  libgomp1                     :armhf  6.3.0-18+rpi1                 6.3.0-18+rpi1+deb9u1
2018-03-05  15:56:23  install  mpg123                       :armhf  <none>                        1.23.8-1
2018-03-05  15:56:23  install  libout123-0                  :armhf  <none>                        1.23.8-1
2018-01-22  17:09:45  install  libmailtools-perl            :all    <none>                        2.18-1
2018-01-22  17:09:44  install  libnet-smtp-ssl-perl         :all    <none>                        1.04-1

欠点:

  • 上記のように、ARMアーキテクチャでのみ機能し、アーキテクチャのフィールドセパレータにわずかな変更が必要です
  • エイリアスを簡単にするためにスクリプトに入れる必要がある
  • 他の* nixシステムではテストされていません

1

他のディストリビューションの回答を歓迎していると述べているため、これに注意してください。rpmには多数の出力形式タグがあり、そのうちの1つはINSTALLTIMEです。(wget例として使用)

rpm -qi wget --qf "%{NAME},%{INSTALLTIME}\n" | tail -n 1
wget,1454014156

これはいくつかの方法でフォーマットできます。私はこのように使用します:

rpm -qi wget --qf "%{NAME},%{INSTALLTIME:date}\n" | tail -n 1
wget,Thu 28 Jan 2016 03:49:16 PM EST

これら2つのページには、RPMメタデータの問題の解決に関する膨大な情報があります。

http://www.rpm.org/max-rpm/s1-rpm-query-parts.html

http://www.rpm.org/max-rpm/s1-rpm-query-handy-queries.html

この情報を並べ替えることで、問題の実用的な解決策が得られます。


1

GNU / Linux Debianにはこの問題に対する組み込みツールはありませんが、標準的な方法でインストールされたプログラムに関するすべての情報は、/ var / lib / dpkg / info /にあるprogram-name.listのファイルに保存されます。ただし、手動でインストールされたプログラムに関する情報はありません。


長い単一行ソリューション

for file_list in `ls -rt /var/lib/dpkg/info/*.list`; do \
    stat_result=$(stat --format=%y "$file_list"); \
    printf "%-50s %s\n" $(basename $file_list .list) "$stat_result"; \
done

説明

  1. ls -rt日付変更によって逆順で、つまりリストの最後に最新のファイルでソートされたファイルを出力します。
  2. stat ファイルの日付を人間が読める形式で出力します。
  3. printf パッケージ名と最終変更日を表示します。
  4. for最古から最新までの全体を印刷パッケージ名や日付などのループ。

出力例(切り捨て):

.........................................
gnome-system-log                            2016-09-17 16:31:58.000000000 +0300
libyelp0                                    2016-09-17 16:32:00.000000000 +0300
gnome-system-monitor                        2016-09-17 16:32:00.000000000 +0300
yelp-xsl                                    2016-09-17 16:32:01.000000000 +0300
yelp                                        2016-09-17 16:32:03.000000000 +0300
gnome-user-guide                            2016-09-17 16:32:18.000000000 +0300
libapache2-mod-dnssd                        2016-09-17 16:32:19.000000000 +0300
.........................................
linux-compiler-gcc-4.8-x86                  2017-02-26 20:11:02.800756429 +0200
linux-headers-3.16.0-4-amd64                2017-02-26 20:11:10.463446327 +0200
linux-headers-3.16.0-4-common               2017-02-26 20:11:17.414555037 +0200
linux-libc-dev:amd64                        2017-02-26 20:11:21.126184016 +0200
openssl                                     2017-02-26 20:11:22.094098618 +0200
unzip                                       2017-02-26 20:11:23.118013331 +0200
wireless-regdb                              2017-02-26 20:11:23.929949143 +0200
nodejs                                      2017-02-26 20:11:33.321424052 +0200
nasm                                        2017-02-28 16:41:17.013509727 +0200
librecode0:amd64                            2017-03-01 10:38:49.817962640 +0200
libuchardet0                                2017-03-01 10:41:10.860098788 +0200
tree                                        2017-03-04 14:32:12.251787763 +0200
libtar0                                     2017-03-07 09:51:46.609746789 +0200
libtar-dev                                  2017-03-07 09:51:47.129753987 +0200

このソリューションの主な欠点は、実稼働環境で十分にテストされていないことです。


これは、仕事をほぼ完了させる美しいソリューションです。唯一の欠点は、(1)非常に遅いこと、および(2)パッケージが最後に更新されたときのみ表示され、以前のバージョンではないことです。もちろん、これはワンライナーの問題ではありませんが、dpkgがで履歴を追跡しない方法/var/lib/dpkg/info/です。それが、使用/var/log/dpkg.log*が好ましい理由でもあります。
not2qubit

1

ラフですが、他のソリューションと同様に迅速に機能します。日付形式はyyyymmddhhmmssです。つまり、ビットまたは並べ替えと形式の削除により、ソート可能な数値が生成されます。

他のソリューションのおかげで、コピーを作成するために構築されたオペレーティングシステムで使用できるパッケージ名がインストール順にリストされています。

find /var/lib/dpkg/info -name "*.list" -exec stat -c $'%n\t%y' {} \; \
| sed -e 's,/var/lib/dpkg/info/,,' -e 's,\.list\t,\t,' \
| sort | awk '{print $2$3" "$1}' | sed '0,/RE/s/-//' \
| sed '0,/RE/s/-//' | sed '0,/RE/s/://' | sed '0,/RE/s/://' \
| sed '0,/RE/s/\\.//' | sed 's/:armhf//' | sort | awk '{print $2}'

@ alexander-caveへようこそ!予想される出力の種類を確認できるように、数行の出力を追加してください。
not2qubit
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.