The Relationship Between
dir are separate programs that behave similarly. As explained and referenced below, the purpose of
dir is to provide a command like
ls whose output does not vary depending on whether or not it is going to a terminal. To achieve this helpfully,
dir must format its output in a way that is reasonable and useful both for viewing in a terminal and for writing to a file or pipe.
There are two common misconceptions about
- Many people believe
dir is an alias of
ls, but that is not the case. Neither command is an alias of the other, and by default in Ubuntu,
dir is not an alias at all.
dir are provided by separate, non-identical executables.
- Many people believe
dir exists for obscure historical reasons or to provide compatibility with some standard or some other OS. That is not the case either.
ls behaves the way it does for compatibilty.
dir, which doesn't have to be compatible because it's not a standard Unix command, behaves in an alternate way that the developers consider valuable in its own right and possibly even preferable.
OK, but exactly how do
dir list the contents of directories. Two specific differences in their default behaviors distinguish them.
When its standard output is a terminal,
ls lists filenames in vertically sorted columns (like
ls -C). When its standard output is not a terminal (for example, a file or pipe),
ls lists filenames one per line (like
Whether or not its standard output is a terminal,
dir lists filenames in vertically sorted columns (like
dir, these defaults may be overridden by the
--format= flag and by the
-x flags, which abbreviate particular
--format= options. See 10.1.4 General output formatting in the GNU coreutils reference manual for details.
When its standard output is a terminal and a filename to be listed contains control characters,
? instead of each control character (like
ls -q). When its standard output is not a terminal,
ls prints control characters as-is (like
Whether or not its standard output is a terminal, when
dir encounters a control character or any other character that would be interpreted specially if entered into a shell, it prints backslash sequences for the characters. This includes even relatively common characters like spaces. For example,
dir will list an entry called
Documents backups as
Documents\ backups. This is like
dir, these defaults may be overridden by the flags listed in 10.1.7 Formatting the file names in the GNU coreutils reference manual. This includes
--quoting-style=, and some others.
Sources: ls invocation and dir invocation, in the GNU coreutils reference manual.
The rationale for a separate
dir utility is given in 4.5 Standards for Interfaces Generally of the GNU coding standards. I recommend reading that whole section to understand the developers' reasoning, but here are the highlights as applicable to
Please don’t make the behavior of a utility depend on the name used to
Instead, use a run time option or a compilation switch or both to
select among the alternate behaviors....
Likewise, please don’t make the behavior of a command-line program
depend on the type of output device....
Compatibility requires certain programs to depend on the type of
output device. It would be disastrous if
sh did not do so in
the way all users expect. In some of these cases, we supplement the
program with a preferred alternate version that does not depend on the
output device type. For example, we provide a
dir program much like
ls except that its default output format is always multi-column
The GNU Project considers it undesirable, from a technical perspective, for a utility to produce different output depending on what kind of device it is writing to (at least in the utility's default configuration). For some utilities, including
ls, device-dependent output is necessary for compatibility and so it works the way users expect. Some users do also specifically prefer this device-dependent behavior.
ls could not reasonably be written to behave device independently, a separate
dir utility was created to achieve this. Thus
dir is not the utility that behaves strangely for reasons of historical compatibility--
To see how
dir, and the related
vdir utility are implemented in the coreutils source code without needless code duplication, see
dir really useful?
If you've ever wished
ls produced multi-column output even when you piped it to
ls | less) or redirected it to a file (
ls > out.txt), you can use
If you've ever wished you could directly copy a filename shown by
ls and use it as part of a command without worrying about quoting, you can use
dir is equivalent to
ls -Cb, so in that sense you don't need
dir provides a combination of options that in practice is often useful (though not widely known about).
Why do I get colorized output from
ls -Cb) but not
Most Ubuntu users have an alias called
ls which runs
ls --color=auto. When
ls exists both as an alias and an external command, the alias takes precedence in simple, interactive commands.
Alias definitions aren't expanded recursively--it's the external
ls command that the
ls alias is calling with
--color=auto. See 6.6 Aliases in the Bash reference manual for more information on how aliases work.
When passed to
vdir (and some other commands, like
--color=auto uses color when its output is a terminal, but not otherwise.
By default in Ubuntu, user accounts are created with this in
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
You'll notice the
ls alias (
alias ls='ls --color=auto') is uncommented, while those for
vdir are commented out with
# so they take no effect. That is, while
dir is not an alias,
ls is (but not to
How do I make
dir produce colored output, too?
To enable colored output with
dir, simply edit
.bashrc in your home directory and uncomment the
#alias dir='dir --color=auto' line by removing the leading
#. In shells started after the change,
dir will be an alias.
If you want the change in the current shell, you can run the alias definition as a command, or you can source
.bashrc by running
This arguably goes against the main point of
dir--that it should produce the same sort of output regardless of the output device. However:
- If you find it useful to make this
dir alias, you should certainly do so.
- When called as an external command, for example in scripts or if you override the alias by running
dir will still produce device-independent output. This is to say that aliasing
dir --color=auto does not really break