You can use readlink
to print where a link points to. The argument to readlink
without options has to be a link, if you pass it a file, it will not print anything. The -f
option for readlink
, from the coreutils package, recursively follows links and prints the filename even if the argument already is a file.
If you do (-n
supresses the newline at the end of the readlink
output):
dpkg -S "$(readlink -fn "$(which rename)")"
You will get as answer:
perl: /usr/bin/prename
that a link was followed is in this case clear from the prename
, but this is not guaranteed to be the case (e.g. if a link was pointing to an executable rename
in a directory that is not in your $PATH).
As @011c indicated, and if you have it installed, you can use realpath
as alternative to readlink -f
apt-cache showpkg
shows detailed information about potentially installable packages. It does indicate whether the package is installed, kind of, but not in a very readable way:
Versions:
2:3.6.6-6+deb7u5 (/var/lib/apt/lists/mirrordirector.raspbian.org_raspbian_dists_wheezy_main_binary-armhf_Packages)
If the package was installed, you'd see (/var/lib/dpkg/status)
at the end of the line. However, this isn't fully reliable, because you'd also see this indication if the package was known to your system but not fully installed, e.g. if it was in the “package uninstalled but configuration files left over” state.
A more useful apt-cache
subcommand is apt-cache policy
. It clearly shows the installed version (if any) and the available version(s). For example, here's output from a machine which has samba
installed but not samba-dev
:
samba:
Installed: 2:4.1.17+dfsg-2
Candidate: 2:4.1.17+dfsg-2
Version table:
*** 2:4.1.17+dfsg-2 0
500 http://ftp.fr.debian.org/debian/ jessie/main amd64 Packages
100 /var/lib/dpkg/status
samba-dev:
Installed: (none)
Candidate: 2:4.1.17+dfsg-2
Version table:
2:4.1.17+dfsg-2 0
500 http://ftp.fr.debian.org/debian/ jessie/main amd64 Packages
Alternatively, you can use the dpkg
command to get information about your current system. APT is the software that manages the download of packages, dependency analysis, etc. Dpkg is the low-level software that carries out the actual installation of a package file.
dpkg -l samba
This shows a line beginning with i
if the package is installed, and a line beginning with u
or p
or nothing at all if the package is not installed.
$ dpkg -l samba samba-dev
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
+++-==============-============-============-=================================
ii samba 2:4.1.17+dfs amd64 SMB/CIFS file, print, and login s
dpkg-query: no packages found matching samba-dev
(dpkg-query
is the dpkg
subcommand that returns information about the package database.)
Note that if you just want to ensure that a package is installed, you can simply run
apt-get install samba
This won't do anything if the latest version of the package that's available in your distribution is already installed. It will install the package if it isn't installed yet, and it will upgrade it if you have an older version.
Best Answer
dpkg -S
can't tell you which package installed the symlink because it only looks at the files that were unpacked from the packages. This information is provided by the*.list
files in/var/lib/dpkg/info/*.list
.Every file on a Debian system can only be owned by one package. If you try to install a package that contains a file that is already provided by another package, one of the following things will happen:
dpkg
will refuse to install the second package.dpkg
will remove the first package before it installs the second package (if the second package specifies aBreaks
orConflicts
relationship to the first package).dpkg
will upgrade the first package to a newer version that no longer provides the file before it installs the second package (if the second package specifies aConflicts
/Breaks
and aReplaces
relationship to the first package).dpkg
will install the second package alongside the first package, and will overwrite the file with the one provided by the second package (if the second package specifies aReplaces
relationship to the first package).Obviously, this doesn't really allow for multiple packages that provide the same command and can be installed at the same time, so this is where the
alternatives
system of Debian comes in. The packages provide their files with different names, for example:and the package
postinst
script (/var/lib/dpkg/info/perl.postinst
) registers it as an alternative:That is the reason why
dpkg -S
doesn't know about/usr/bin/rename
.Debian packages can provide symlinks, so as long as it's not an
alternatives
symlink (or a symlink that was created by thepostinst
for some other reason),dpkg -S
will work fine.In the case of the
alternatives
system, just follow the symlink trail:Of course this may lead you to wrong conclusions for example when a package creates a symlink in it's
postinst
that points to a file provided by another file. In such cases, there's no general way to figure out the responsible package - you will have to do some detective work, for example bygrep
ping through the*.postinst
files.