我需要在debian / ubuntu上执行此操作。其他发行版的答案也将很好。
我安装了很多东西来编译某些代码,并且我想获得必须安装的软件包的列表。
#1 楼
像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
构建已安装软件包的列表
q4 312078q
加入2个列表
$ dpkg --get-selections | sed -ne '/\tinstall$/{s/[[:space:]].*//;p}' | \
sort > ~/dpkglist.selections
由于某种原因,它对我的打印差异不大,因此可能存在错误或错误关于
--get-selections
的含义的无效假设。您显然可以使用
find . -mtime -<days>
或head -n <lines>
来限制软件包,并根据需要更改输出格式,例如$ join -1 1 -2 1 -t $'\t' ~/dpkglist.selections ~/dpkglist.dates \
> ~/dpkglist.selectiondates
仅列出过去4天安装(更改?)的选件。
您还可以在验证
sort
所使用的排序顺序后删除dpkg --get-selections
命令,并进行find
命令更有效。评论
我通常更喜欢apt-get而不是rpm,但是现在debian因为未将安装日期保存在数据库中而得到-1。 debian技巧包括所有已安装的软件包,而不仅仅是选定的软件包,但这是一个好的开始。
– Elazar Leibovich
2011年5月4日下午6:53
对于Debian,如果您这样做,您的工作量就会减少(删除半安装的条目):grep install \ /var/log/dpkg.log
–皮尔兹
16年11月22日在16:13
@Mikel-好答案。我扩展了“收集/var/lib/dpkg/info/*.list文件信息”的内容,并添加了代码以过滤除“顶级程序包”(没有其他atp程序包依赖的atp程序包)之外的所有代码。该
–克雷格·希克斯(Craig Hicks)
17年8月22日在5:26
Debian / Ubuntu:grep“ install” /var/log/dpkg.log仅列出“安装”行,而不显示“状态”行。
–甜点
17年12月20日在19:54
如果apt或dpkg都没有存储安装/修改的日期时间,那么在2019年,这对于我来说似乎是不可接受的。我们依赖于grepping日志文件,该文件是否仍在计算机上?情况如何?
–theferrit32
19年2月14日在18:33
#2 楼
Mikel已展示了如何在dpkg级别执行此操作。特别是,/var/lib/dpkg/info/$packagename.list
是在安装软件包时创建的(以后不会进行修改)。如果您使用的是APT工具(由于担心自动和手动安装的软件包,所以应该这样做),
/var/log/apt/history.log
有历史。只要没有旋转,它就会跟踪所有APT的安装,升级和删除,并带有标记为自动安装的软件包的注释。这是APT 0.7.26中引入的一项相当新的功能,因此在Debian中它受到挤压。在Ubuntu中,10.04的版本为history.log
,但是直到10.10才提供自动安装的注释。评论
正如Mikel指出的那样:“最终,旧的/var/log/dpkg.log.*文件将通过日志轮换删除,因此不能保证这种方式可以为您提供系统的整个历史记录。”请参阅此
–克雷格·希克斯(Craig Hicks)
17年8月22日在5:38
#3 楼
粗糙,但是可以工作: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 , , }'` : " ;
( ( grep -A3 " ${lint}$" /var/lib/apt/extended_states | \
grep '^Auto' > /dev/null ) && echo "Auto" ) || echo "Manual" ;
done > pkgdatetime.txt
评论
Boo,嘶嘶声,用于解析ls的输出。请参阅mywiki.wooledge.org/ParsingLs,以获取有关为什么这样做很危险/固有错误的注释-较安全的选择是使用find -printf或stat --format生成可以明确解析的流。
–查尔斯·达菲(Charles Duffy)
2015年4月10日17:17
@CharlesDuffy不错的链接,但是为了简单起见,使用ls -al --time-style = long-iso应该会有所帮助。另外,可能还没有听说有人会用\ n \ t \ r \ v来命名APT软件包。
–not2qubit
18年4月26日在11:12
#4 楼
/var/log/apt/history.log
文件的格式笨拙,恕我直言。开始日期:{date} {time}
命令行:{command} {options ...}
安装:{package(version)},...,{package(version)},
...
结束日期:{date} {time}
我希望有更多日志文件格式的记录
{date} {time} {tab} {package} {tab} {version} {tab} {command} {options} \ n
或一些XML,它们不仅显示{package},而且还显示任何{dependencies}。
当前执行的操作中,您可以发现信息您正在寻找,但需要进行一些取证处理才能提取出细节。
#5 楼
这是每个人都想要和需要的一线: for x in $(ls -1t /var/log/dpkg.log*); do zcat -f $x |tac |grep -e " install " -e " upgrade "; done |awk -F ":a" '{print " :a" }' |column -t
结果将显示全部(新)按时间顺序安装和升级的软件包。
行说明:
ls -1t
-按时间顺序获取所有dpkg.log*
文件名zcat -f
-IF文件是gzip类型,然后将其解压缩,ELSE只需传递内容。tac
-cat的反向输出,逐行显示以确保我们获得正确的时间顺序。grep
-仅检查已安装或升级的软件包。awk -F ':a'
-从软件包名称中分离体系结构字段column -t
-漂亮地打印用空格分隔的列当然想为此做一个别名,但是不幸的是这是不可能的,因为awk取决于单引号和双引号。在这方面,最好将其放入bash脚本中,并在field列中更好地处理
:
分隔符以用于其他体系结构。 输出为:
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系统上进行过测试
#6 楼
这对我在Debian系统上有效,我猜测文件格式自2011年以来已经更改。该系统非常新,因此我不希望此在较旧的系统上运行,尽管可能只需要解压缩即可
grep 'install ' /var/log/dpkg.log.1 | sort | cut -f1,2,4 -d' '
文件
/var/log/dpkg.log
每行的前两个字段是日期和时间。请注意grep部分中带有install的尾随空格,这是因为升级可以触发安装,但是如果我理解正确的话,您想知道用户安装了什么。评论
就是我做的简单。但是您可以使用zgrep,您所有的.gz日志都会像zgrep'install'/var/log/dpkg.log*一样被搜索。在“安装”一词前放置空格,以防止讨厌的“半安装”。我必须使用cut -f1,5来获取包名字段。当然,最终旧的原木会旋转出来。
– geoo
17-4-24在9:19
#7 楼
GNU / Linux Debian没有用于解决此问题的内置工具,但是有关以标准方式安装的程序的所有信息都保存在程序名称为.list的文件中的/ var / lib / dpkg / info /中。但是那里没有有关手动安装程序的信息。一个很长的单行解决方案:
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
说明:
ls -rt
输出按日期修改以相反顺序排列的文件,即最新文件位于列表末尾。stat
以易于阅读的形式打印文件的日期。printf
显示程序包名称和上次修改的日期。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
18年4月26日在11:49
#8 楼
注意这一点是因为您提到欢迎其他分发答案。 rpm具有大量的输出格式标签,其中之一是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
这两个页面提供了大量有关解决RPM元数据问题的信息:
http:/ /www.rpm.org/max-rpm/s1-rpm-query-parts.html
http://www.rpm.org/max-rpm/s1-rpm-query-handy- query.html
对这些信息进行排序将为您的问题提供有效的解决方案。
#9 楼
它很粗糙,但是和其他解决方案一样快。日期格式为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 " "}' | 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 }'
评论
欢迎@ alexander-cave!请添加几行输出,以便人们可以看到期望的输出类型。
–not2qubit
18/09/5在19:50
#10 楼
使用apt中轮换的日志文件,您可以:zcat -f /var/log/dpkg.log* | grep " install " | less
#11 楼
我已经使用以下命令在Kubuntu上实现了它:列出软件包。
读取每个标准输入。
以“%”格式存储完整路径(路径|创建日期) n |%y“放入变量中。
将文件名存储到变量中
如果成功执行了前面的两个命令,则值将打印在一行中。
ls /var/lib/dpkg/info/*.list |while read xfile; do wpath=$(stat -c '%n|%y' ${xfile}) && wfile=$(basename ${xfile}) && printf "${wfile}|${wpath}\n" ;done
最好的问候,
评论
另请参阅如何获取apt-get安装的历史记录。我一直在搜索“ apt发布日期”,但没有运气,也许此评论会对将来的Googlers有所帮助。
Askubuntu.com上的类似问题“如何列出所有已安装的软件包”。