What are all the Ubuntu one letter commands?
I came across this command whilst setting up ssh
:
$ w
20:01:30 up 6 days, 2:20, 3 users, load average: 0.06, 0.11, 0.10
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
rick tty7 :0 16Jun20 6days 16:51 2.37s /sbin/upstart --user
rick pts/21 192.168.0.12 18:44 1:14m 0.19s 0.00s sleep 60
rick pts/22 192.168.0.12 18:45 0.00s 0.44s 0.01s w
Which led me to wonder what all the one letter commands are in Ubuntu. I didn't find an exact reference but I found this website:
- An A-Z Index of the Linux command line: bash + utilities.
Here the w
command is listed along with:
-
.
the command to source a file which I've used -
v
is a command not installed in Ubuntu. It is said to be equivalent tols -l -b
. This in turn is similar to the thell
alias setup by Ubuntu except files beginning with.
(including the infamous.
and..
) are not included.
Are there other one letter commands installed within Ubuntu by default?
TL;DR: This tells you about each command whose name is a single character, though you may want to simplify or otherwise adjust it:
(set -f; type -a $(compgen -cX '!?' | sort -u))
Listing one-character commands with compgen
Bash has tab completion and offers a compgen
builtin, which provides insight into how text is completed. By running compgen -c
, you can list all the commands on your system. So one way to list all commands that are just one character long is to filter the output of compgen -c
:
compgen -c | grep '^.$'
As steeldriver has pointed out, compgen
accepts an -X
option to do its own filtering. Somewhat nonintuitively, the operand to -X
is a pattern whose matches are removed. It supports globbing syntax that works like filename expansion, but also supports an initial !
to negate it, achieving the desired effect here. (See Programmable Completion Builtins for more information about the syntax.) ?
matches any single character, so !?
matches anything that is not a single character, so -X '!?'
removes everything that is not a single character, leaving only single-character commands:
compgen -cX '!?'
That shows the same results, in the same order, as piping to grep
. You can pass -c
and -X
in one argument as -cX
or (as steeldriver shows it) in two arguments as -c -X
.
On my system, I get:
l
p
{
}
!
.
:
[
s
t
[
X
w
s
and t
on my system are scripts I wrote; you most likely don't have commands with those names. You likely do have the others.
Whether these are all really commands or not depends on what one thinks of as a command. {
, }
, and !
are shell keywords, like if
, case
, while
, and for
. The others (including shell builtins) are unambiguously commands in the usual sense.
The meaning of repeated results
Some commands, such as [
in the above output, may be repeated. This happens when more than one command of the same name exists. Bash offers [
as a shell builtin, but it is also an executable located in /usr/bin
. Running type cmd
shows what type of command cmd
is and, if it is an external command, where it is located. When there is more than one command of the same name, it shows the one that will actually be used. As Kulfy has pointed out, you can see them all using type -a cmd
.
$ type -a [
[ is a shell builtin
[ is /usr/bin/[
There's another source of possible duplication: on some systems, /bin
and /usr/bin
are actually the same directory (more precisely: /bin
is a symlink to /usr/bin
) and you'll see entries in both /bin
and /usr/bin
. For example, you may have both /bin/[
and /usr/bin/[
as well as the [
builtin, as well as both /bin/w
and /usr/bin/w
and both /bin/X
and /usr/bin/X
. These are technically separate commands, but they actually refer to the same executable.
Traditionally, /bin
and /usr/bin
were separate directories (so that commands in /bin
would be usable even when /usr
is an NFS volume that is not yet mounted). But these days this doesn't usually offer a benefit. So newer systems tend to unify them. If you're using a newer release, you probably have this, unless you upgraded to it from an older release that did not.
If you like, you can sort the output of compgen
and remove duplicates:
compgen -c | grep '^.$' | sort -u
compgen -cX '!?' | sort -u
Showing details on all the commands
For more detail, you might wish to know what type of command each one is and:
- for the external commands, where they are located.
- for aliases and shell functions, how they are defined.
As mentioned above, Bash's type
builtin will tell you all this. You can write a command that supplies the filtered output of compgen
to type
.
type $(compgen -c | grep '^.$')
type $(compgen -cX '!?')
That will behave badly if you have a *
or ?
command. That's quite unlikely, but not impossible. To safeguard against that, you may want to disable globbing:
(set -f; type $(compgen -c | grep '^.$'))
(set -f; type $(compgen -cX '!?'))
But this (with any of those four alternatives) is imperfect, because all commands of the same name have the same explanation, which is only correct for the first one. For example, on my system, I get:
l is aliased to `ls -CF'
p is aliased to `printf "\e[?2004l"'
{ is a shell keyword
} is a shell keyword
! is a shell keyword
. is a shell builtin
: is a shell builtin
[ is a shell builtin
s is /home/ek/bin/s
t is /home/ek/bin/t
[ is a shell builtin
X is /usr/bin/X
w is /usr/bin/w
You may very well only want to see information about the first occurrence of each command of the same name (e.g., the shell builtin [
). After all, those are the ones that actually run, when you write a command whose first word is any of those one-character names (e.g., [ -f /bin/nano ]
runs the shell builtin [
, not /usr/bin/[
). If so, you can sort the output of compgen
and remove duplicates before handing the results to type
:
type $(compgen -c | grep '^.$' | sort -u)
type $(compgen -cX '!?' | sort -u)
Or, to also safeguard against globbing:
(set -f; type $(compgen -c | grep '^.$' | sort -u))
(set -f; type $(compgen -cX '!?' | sort -u))
However, if you want information about all the commands (e.g., /usr/bin/[
as well as [
), then you can pass -a
to type
. I recommend that you still sort and remove duplicates from the results first, or you'll get lots of repetition in the output.
type -a $(compgen -c | grep '^.$' | sort -u)
type -a $(compgen -cX '!?' | sort -u)
Or, to also safeguard against globbing:
(set -f; type -a $(compgen -c | grep '^.$' | sort -u))
(set -f; type -a $(compgen -cX '!?' | sort -u))
What commands you have varies across shell environments
Note that which one-character commands you have, like which commands you have in general, is a property of your shell environment. Different users, or different running shells by the same user, may have different commands available. The l
command in Ubuntu, for example, is defined in /etc/skel/.bashrc
, which is copied to ~/.bashrc
when user accounts are created in the usual way.
# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
You can thus change or remove the definition of l
in your per-user ~/.bashrc
. Or simply run unalias l
to affect just your current shell.