如何查詢某個檔案,屬於哪個套件
測試環境
以下測試是在「Xubuntu 14.04 64位元」。
前提
以「uname」這個指令為例
uname 用法範例
$ uname -a
操作步驟
執行
$ dpkg -S uname
會看到(依照系統安裝的套件而定)
manpages-posix: /usr/share/man/man1/uname.1posix.gz
coreutils: /usr/share/man/man1/uname.1.gz
manpages-dev: /usr/share/man/man2/oldolduname.2.gz
python3.4-examples: /usr/share/doc/python3.4/examples/scripts/find-uname.py
python2.7-examples: /usr/share/doc/python2.7/examples/Demo/scripts/find-uname.py
coreutils: /bin/uname
klibc-utils: /usr/lib/klibc/bin/uname
manpages-dev: /usr/share/man/man2/olduname.2.gz
manpages-posix-dev: /usr/share/man/man3/uname.3posix.gz
manpages-dev: /usr/share/man/man2/uname.2.gz
然後執行
$ whereis uname
會顯示
uname: /bin/uname /usr/share/man/man2/uname.2.gz /usr/share/man/man1/uname.1posix.gz /usr/share/man/man1/uname.1.gz /usr/share/man/man3/uname.3posix.gz
可以知道「uname」這個指令,是放在「/bin/uname」這個路徑。
執行
$ dpkg -S /bin/uname
會看到
coreutils: /bin/uname
最後就可以知道,「uanme」這個指令是屬於「coreutils」這個套件。
注意要有安裝該套件,才有辦法使用「dpkg -S」查到。
$ cat /var/lib/dpkg/info/coreutils.list | grep uname
例外狀況
另外有種狀況,即使你安裝了該套件,但有些檔案,你也查不到是屬於哪個套件了。
因為該檔案是透過「MaintainerScripts」或是「DpkgTriggers」的機制產生的。
例如:你查不到「/etc/networks」。
$ dpkg -S /etc/networks
會顯示
dpkg-query: no path found matching pattern /etc/networks
你可以觀看「/var/lib/dpkg/info/base-files.postinst」。
$ cat /var/lib/dpkg/info/base-files.postinst | grep networks
可以看到一行
install_from_default /usr/share/base-files/networks /etc/networks
查看一下「/usr/share/base-files/networks」和「/etc/networks」
cat /usr/share/base-files/networks
cat /etc/networks
所以用「dpkg -S」找不到檔案屬於哪個套件,可以嘗試到「/var/lib/dpkg/info/」去找。
$ grep '/etc/networks' /var/lib/dpkg/info/ -R
附帶一提
另外在「/var/lib/dpkg/info/」可以看到一些跟「base-files」有關的檔案
$ ls /var/lib/dpkg/info/base-files* -1
會顯示
/var/lib/dpkg/info/base-files.conffiles
/var/lib/dpkg/info/base-files.list
/var/lib/dpkg/info/base-files.md5sums
/var/lib/dpkg/info/base-files.postinst
/var/lib/dpkg/info/base-files.postrm
/var/lib/dpkg/info/base-files.preinst
你可以下載「base-files」,「解開來看」。
apt-get download base-files
dpkg -e base-files_7.2ubuntu5.2_amd64.deb
tree DEBIAN
就會看到
DEBIAN
├── conffiles
├── control
├── md5sums
├── postinst
├── postrm
└── preinst
0 directories, 6 files
確認一下「DEBIAN/postinst」是不是和「/var/lib/dpkg/info/base-files.postinst」一樣。
執行
$ md5sum DEBIAN/postinst
顯示
29eac8bafe921c9e7a537cd58e272fae DEBIAN/postinst
執行
$ md5sum /var/lib/dpkg/info/base-files.postinst
顯示
29eac8bafe921c9e7a537cd58e272fae /var/lib/dpkg/info/base-files.postinst
另一個檔「/etc/default/locale」也是蠻特殊的,「dpkg -S」找不到。
執行
$ dpkg -S /etc/default/locale
顯示
$ dpkg-query: no path found matching pattern /etc/default/locale
所以
$ grep '/etc/default/locale' /var/lib/dpkg/info/ -R
會顯示
/var/lib/dpkg/info/dictionaries-common.config: # If system is already installed use /etc/default/locale contents.
/var/lib/dpkg/info/dictionaries-common.config: if ( -e "/etc/default/locale" ){
/var/lib/dpkg/info/language-selector-common.postinst:if dpkg --compare-versions "$2" lt-nl 0.85 && [ -e /etc/default/locale ] \
/var/lib/dpkg/info/language-selector-common.postinst: . /etc/default/locale
待研究...
例外狀況 - alternatives
另外有一種情況,是透過「update-alternatives」的方式。
例如「/usr/bin/write」。
執行
$ type write
顯示
write is /usr/bin/write
執行
$ whereis write
顯示
write: /usr/bin/write /usr/bin/X11/write /usr/share/man/man2/write.2.gz /usr/share/man/man1/write.1posix.gz /usr/share/man/man1/write.1.gz /usr/share/man/man3/write.3posix.gz
執行
$ dpkg -S /usr/bin/write
顯示
dpkg-query: no path found matching pattern /usr/bin/write
執行
$ ls /usr/bin/write -l
顯示
lrwxrwxrwx 1 root root 23 Apr 21 2014 /usr/bin/write -> /etc/alternatives/write
執行
$ ls /etc/alternatives/write -l
顯示
lrwxrwxrwx 1 root root 18 Apr 21 2014 /etc/alternatives/write -> /usr/bin/bsd-write
執行
$ dpkg -S /usr/bin/bsd-write
顯示
bsdmainutils: /usr/bin/bsd-write
最後就找到「bsdmainutils」這個套件。
參考
- man dpkg
- man dpkg-query
- Debian Wiki / MaintainerScripts
- Debian Wiki / DpkgTriggers
- vim /usr/share/doc/dpkg-dev/triggers.txt.gz
- man dpkg-trigger
- man deb-triggers