Why dpkg -S May Not Find /usr/bin/bash on Ubuntu
Background
When working on Ubuntu or Debian systems, it is common to ask a simple question:
Which package owns this executable?
For example, you may try:
dpkg -S /usr/bin/bash
dpkg -S /usr/bin/dash
Surprisingly, these commands may return no result, even though both commands clearly exist on the system:
which bash
which dash
The output may be:
/usr/bin/bash
/usr/bin/dash
Even more confusingly, searching Ubuntu’s package contents website may also fail when using the /usr/bin/... path, for example:
https://packages.ubuntu.com/search?mode=exactfilename&searchon=contents&keywords=%2Fusr%2Fbin%2Fbash
This looks contradictory at first, but the reason is the interaction between package file lists, $PATH, and the merged /usr filesystem layout.
The Short Answer
On many modern Ubuntu systems, /bin is a symbolic link to /usr/bin:
/bin -> /usr/bin
So these two paths may refer to the same executable:
/bin/bash
/usr/bin/bash
However, dpkg records the file path that the package declares in its package file list. For historical and compatibility reasons, packages such as bash and dash may still be registered as owning:
/bin/bash
/bin/dash
not:
/usr/bin/bash
/usr/bin/dash
Therefore, this may fail:
dpkg -S /usr/bin/bash
but this should work:
dpkg -S /bin/bash
Typical output:
bash: /bin/bash
And similarly:
dpkg -S /bin/dash
Typical output:
dash: /bin/dash
What dpkg -S Actually Does
dpkg -S searches the local Debian package database for a file path.
For example:
dpkg -S /bin/bash
asks:
Which installed package registered
/bin/bashin its file list?
It does not ask:
Which package owns the inode that
/usr/bin/basheventually resolves to?
That distinction matters.
dpkg -S performs a package database lookup based on recorded path names. It does not automatically canonicalize paths through symbolic links, and it does not automatically treat /bin/bash and /usr/bin/bash as interchangeable strings.
So if the package database records:
/bin/bash
then searching for:
/usr/bin/bash
may not match, even if both paths point to the same executable at runtime.
Why which dash Shows /usr/bin/dash
The which command is different from dpkg -S.
which searches executable names through the directories listed in $PATH.
For example, a typical Ubuntu $PATH may look like this:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Notice that /usr/bin appears before /bin.
When you run:
which dash
which checks the directories in $PATH order and finds:
/usr/bin/dash
Because /bin is commonly a symbolic link to /usr/bin, /bin/dash and /usr/bin/dash are effectively the same executable. But which only reports the first matching path it finds through $PATH.
This is why the following two facts can both be true:
which dash
outputs:
/usr/bin/dash
while:
dpkg -S /bin/dash
outputs:
dash: /bin/dash
They are answering different questions.
Why Ubuntu’s Package Website May Not Find /usr/bin/bash
Ubuntu’s package content search behaves similarly to dpkg -S in this case: it searches package content indexes.
If the package content index records the file as:
/bin/bash
then an exact filename search for:
/usr/bin/bash
may fail.
Instead, search for:
/bin/bash
or:
/bin/dash
This applies especially when using exact filename mode on:
https://packages.ubuntu.com/
The website is not doing a live filesystem lookup on your machine. It is searching package metadata. Package metadata may preserve historical paths such as /bin, even when installed systems expose the same files through /usr/bin because of merged /usr.
Merged /usr: The Source of the Confusion
Historically, Unix-like systems separated directories such as:
/bin
/sbin
/lib
/usr/bin
/usr/sbin
/usr/lib
The original idea was that /bin and /sbin contained essential binaries needed early during boot, while /usr could be a separate filesystem.
Modern Linux systems usually no longer need that strict separation. Many distributions have moved toward a merged /usr layout, where traditional top-level directories are symbolic links into /usr:
/bin -> /usr/bin
/sbin -> /usr/sbin
/lib -> /usr/lib
This simplifies the filesystem layout, but it creates a visible difference between:
- the runtime path that shell tools may find;
- the historical path recorded in package metadata.
That is exactly what happens with bash and dash.
How to Verify on Your Machine
You can inspect the layout with:
ls -ld /bin /usr/bin
If /bin is a symbolic link, you may see something like:
lrwxrwxrwx 1 root root 7 ... /bin -> usr/bin
Then compare the two paths:
ls -li /bin/bash /usr/bin/bash
ls -li /bin/dash /usr/bin/dash
If they point to the same file, the inode information should match.
You can also resolve the canonical path:
realpath /bin/bash
realpath /usr/bin/bash
realpath /bin/dash
realpath /usr/bin/dash
And then query package ownership using the path recorded by the package database:
dpkg -S /bin/bash
dpkg -S /bin/dash
A Practical Debugging Rule
When dpkg -S fails for a path under /usr/bin, try the equivalent traditional path under /bin:
dpkg -S /usr/bin/name
dpkg -S /bin/name
Similarly, for system administration tools, try both:
dpkg -S /usr/sbin/name
dpkg -S /sbin/name
For libraries, the same idea may apply to /lib and /usr/lib, depending on the architecture-specific directory layout.
Command Comparison
| Command | What it searches | Important detail |
|---|---|---|
which dash |
$PATH directories |
Reports the first executable found in runtime search order |
command -v dash |
Shell command resolution | Usually preferred in shell scripts over which |
dpkg -S /bin/dash |
Local package database | Searches recorded package file paths |
| Ubuntu package contents search | Remote package content index | Searches package metadata, not your live filesystem |
realpath /usr/bin/dash |
Filesystem path resolution | Follows symbolic links and prints the canonical path |
Conclusion
The confusing result comes from asking different tools different questions.
which dash answers:
Where does my shell environment find an executable named
dash?
dpkg -S /usr/bin/dash answers:
Which installed package recorded exactly this path in its file list?
On a merged /usr Ubuntu system, /bin/dash and /usr/bin/dash may refer to the same executable, but package metadata may still record the traditional /bin/dash path.
So the reliable command is:
dpkg -S /bin/dash
dpkg -S /bin/bash
And when using Ubuntu’s package website, search for the package metadata path, such as /bin/bash, rather than only the runtime path reported by which.