20

Can a Linux command have capital letter(s)? I know it's supported but i want to be sure if it's a "problem" or considered "not a good thing"?

3
  • 6
    The UNIX convention is to use lowercase for command names, but you're free to call them whatever you wish.
    – user13742
    Mar 28, 2013 at 16:35
  • 1
    Indeed, UNIX doesn't care what you call your commands. It will cause much pain and suffering, but you can even have commands with spaces in them: echo -e '#!/bin/sh\necho hello world' > ~/bin/OH\ NOES; chmod +x ~/bin/OH\ NOES; "OH NOES" produces hello world as expected. (Assuming ~/bin is in your $PATH, of course).
    – derobert
    Mar 28, 2013 at 18:42
  • Check out this question and my perhaps too long tutorial. Mar 29, 2013 at 10:06

6 Answers 6

27

Yes it can, and there are a few already. Such as /usr/bin/X :)

dennis@lightning:~$ ls {/usr{/local,},}/{s,}bin | grep '[A-Z]'
MAKEDEV
amuFormat.sh
GET
HEAD
Mail
POST
X
X11
Xephyr
Xnest
Xorg
NetworkManager

dennis@lightning:~$ zcat ~/.cache/apt-file /archive.ubuntu.com_ubuntu_dists_precise_Contents-i386.gz | tail -n +33 | cut -f1 | grep -P '^(usr/)?s?bin/.*[A-Z]' | wc -l
758

So that's 758 in all of Ubuntu 12.04. Full list: https://gist.github.com/5264777

8
  • No Xdialog? :o And you should quote grep's parameter to avoid the shell expanding it in the current directory before execution.
    – manatwork
    Mar 28, 2013 at 16:34
  • Don't have it installed on this system :) Mar 28, 2013 at 16:35
  • 2
    I would like to insist on quoting grep's parameter: pastebin.com/Gak7x9rN (Yes, I can edit it myself, but I prefer you understand why.)
    – manatwork
    Mar 29, 2013 at 8:28
  • 1
    Well, it may depend on the shell too. I used uppercase in my example for portability, but my bash in my home directory actually expends [A-Z] to “c d f h j m p q r t”. So case insensitively.
    – manatwork
    Mar 29, 2013 at 9:11
  • 1
    Not to mention zsh or bash's failglob option. I personally typically name my temp files (in ~) a, b, c... and my temp dirs A, B, C... Mar 30, 2013 at 0:15
18

There's no restriction on command names on Unix. Any file can be a command. And a filename can be any sequence of one or more (up to a limit though) of characters other than ASCII NUL or ASCII /. zsh even lifts that limitation for functions where you can have any string as the function name.

A few notes though:

  • you'll have a hard time creating a command file called . or .. ;-).
  • avoid names that are already taken by standard commands or shell builtins or keywords (at least of the most common shells like bash, zsh, tcsh or ksh). In that regard upper case characters can help as they are generally not used by standard commands.
  • It's better to restrict to ASCII characters. Non ASCII characters are not expressed the same in the various character sets that are out there
  • while you're at it, restrict yourself to letters, digits, dash, dot and underscore. Anything else, while legal, may cause one problem or another with this or that tool (for instance, |, =, & and many others would need to be escaped in shells, if you use :, your command cannot be used as one's login shell...). You may even want to exclude . and - which are not allowed in function names in many shells, in case you want to allow users to wrap your command in a shell function.
  • Make the first character a letter. Again, not a strict requirement. But underscore is sometimes used for special things (like in zsh the functions from the completion systems start with _), and all-digit commands can be a problem in things like cmd>output.log. Files whose name starts with a dot will be hidden by things like ls or shell globbings and many file managers.
4
  • Right. So I guess it boils down to, don't use anything out of the ordinary unless you have a good reason to do so. Even your second point, I don't think using uppercase to cover those shells are that smart - isn't it better to name the command to describe the change? Like, zsh_with_some_funky_option (instead of ZSH)? Mar 29, 2013 at 10:40
  • Is alias a command? Because if yes, I had very easy time typing alias .="echo Hello" .-) (Well, sudo vim /bin/. was harder, though...) Mar 29, 2013 at 22:11
  • @AloisMahdal That's why I said command file. zsh also allows .() echo Hello. So does pdksh, but the . special builtin takes precedence there. Mar 29, 2013 at 22:22
  • Oops, my misread... Interesting point about the pdksh precedences, though... Mar 29, 2013 at 22:38
6

A few notes on the historical STTY command to clarify some inaccuracies in the other answer and associated comments:

Earlier terminals like the DEC VT05 or VT50 and the teleprinters before that only supported upper case characters. What that meant is that no lower case character could ever be input from them or that they wouldn't be able to display any other letter than upper case ones.

Unix being case sensitive and most commands being lower case, you can see there's an issue there. That's why there are special termio/termios modes (and that are still there in modern Unices even though those terminals are long gone) to handle those.

termio/termios are respectively the older and newer interfaces to control the tty driver on Unix. In a termio(s) ioctl, you specify input, output, control flags... that specify how the electric signals on a serial line are to be handled into input and output characters and the internal behavior of the driver wrt things like echo, the line editor... Most of those apply to virtual terminals like modern Unix VGA consoles or pseudo terminals.

The command line interface to termio(s) is the stty command.

To handle the upper-case terminals, there are three termio(s) flags involved:

  • IUCLC (Input Upper Case to Lower Case): incoming characters are converted to lower case when input. That means the A sent by the terminal is considered as a a. That means that with this on, I can now type LS on my VT50, and the shell will read ls from /dev/ttyX. I can also now run the stty command.
  • Now, with IUCLC alone and terminal echo, while I type LS, the driver would send ls back to the terminal (so I can see what I type) which it can't display, so we also need OLCUC (Output Lower Case to Upper Case), that is we need to convert any lower case letter to uppercase before sending to the terminal.
  • Now, we can operate Unix from a VT50, but what if we want to input upper case characters now? That's where the xcase local flag comes in. This allows (in canonical input mode only) sending an upper case A by typing \A, and on output, an upper case A is rendered as \A. (that one is not implemented on Linux)

The stty command has the corresponding iuclc, olcuc and xcase settings and an alias for all three: lcase. The default setting and what you get after stty sane is lcase off.

So, when you're on a VT50, all you need to do is run:

stty lcase

to be able to do anything. But hold on, how do you do that when you can only send uppercase letters? That's where you need a STTY command as an alias for stty, and that's why stty supports LCASE as an alias for lcase.

There is no such SANE alias because you don't want to do stty sane when your terminal is all-uppercase.

If you run stty lcase or stty olcuc by mistake on a normal terminal (try it in xterm or any modern terminal), that's where you need to enter stty sane to get back to normal. But you don't need a STTY command for that. If you type stty sane, you will see STTY SANE echoed back, but that's only the displayed text (not the entered command) that will have been translated, it's still the stty sane command that will be run.

Those iuclc, olcuc, xcase flags used to be specified by POSIX (and that's probably why it is implemented on Linux even though I seriously doubt anybody ever connected any of those old terminals to a Linux system (other than for fun)), but have been removed in POSIX:2001.

4

The most famous command is stty, which was also available as STTY. It was very handy to set the terminal back to normal behaviour with STTY SANE.

4
  • I have /bin/stty but nothing else. Care to elaborate your answer a bit? Mar 29, 2013 at 10:25
  • 3
    In the good old days, it was possible for your terminal to become so screwed up, that everything was uppercase. So type a and the terminal would see A. To restore sanity, you would use the stty sane command. Except that this now is impossible, therefore having stty available as STTY was very welcome. I can't even remember the last time I needed this though :) Mar 29, 2013 at 10:29
  • @DennisKaarsemaker: WOW! That is some cool piece of history! Mar 29, 2013 at 10:35
  • 1
    Guys (ott-- and @DennisKaarsemaker), you have it backward. I've posted another answer for clarification. Mar 29, 2013 at 22:03
2

On Fedora 18 here:

amuFormat.sh
chkrootkitX
enum_chmLib
enumdir_chmLib
extract_chmLib
fakeCMY
GET
HEAD
Mail
oLschema2ldif
POST
smoltDeleteProfile
smoltGui
smoltSendProfile
smp_conf_zone_man_pass.#prelink#.coLtYv
Terminal
test_chmLib
Thunar
X
Xephyr
xfig-Xaw3d
Xorg
Xvnc
MAKEDEV
NetworkManager
amuFormat.sh
chkrootkitX
enum_chmLib
enumdir_chmLib
extract_chmLib
fakeCMY
GET
HEAD
Mail
oLschema2ldif
POST
smoltDeleteProfile
smoltGui
smoltSendProfile
smp_conf_zone_man_pass.#prelink#.coLtYv
Terminal
test_chmLib
Thunar
X
Xephyr
xfig-Xaw3d
Xorg
Xvnc
MAKEDEV
NetworkManager

For a total of 50 (of which I didn't know most).

1
0

On Debian sid, with zsh, and ls -1 $path | grep '[A-Z]', I get

GET
HEAD
HtFileType
Mail
POST
Pnews
Rnmail
X
X11
Xephyr
Xorg
ircII
amuFormat.sh
hpljP1005
hpljP1006
hpljP1007
hpljP1008
hpljP1505

Edit: Note that, in the command above, that's the digit one, not the letter l. A one as in one column.

4
  • 1
    With zsh, run: type -m '*[A-Z]*' Mar 29, 2013 at 21:11
  • @StephaneChazelas: OK, yours displays the search path, and also includes shell functions. But mine is also zsh-specific: lowercase $path is not in bash, for once. Well, the more information, the better. Mar 30, 2013 at 13:56
  • 1
    Yes, I didn't say yours was wrong, just suggested an alternative (though I'd agree it wasn't the best of wordings). Note that $path is not zsh specific. It comes from csh/tcsh where your command also works. Mar 30, 2013 at 17:02
  • @StephaneChazelas: Aha, that's interesting! No, my command isn't "wrong" but I agree yours is better because it makes sense to include shell functions and aliases. At least for me it does, because when I use my computer, I don't care if it is a binary, a script, a function, an alias, or whatever, as long as I can run it and it does its job. (I guess the -m is for "match".) Mar 31, 2013 at 16:54

You must log in to answer this question.