![](https://csdnimg.cn/release/download_crawler_static/1296163/bg13.jpg)
2.2. ALL THE STARTUP FILES 19
Although you usually know when a shell is interactive, in fact you can test that in exactly
the same way, too: just use ‘[[ -o interactive ]]’. This is one option you can’t change
within the shell; if you turn off reading from the keyboard, where is the shell supposed to
read from? But you can at least test it.
Aside for beginners in shell programming: maybe the semicolon looks a bit funny; that’s
because the ‘then’ is really a separate command. The semicolon is just instead of putting it
on a new line; the two are interchangeable. In fact, I could have written,
if [[ -o login ]]; then; print yes; else; print no; fi
which does exactly the same thing. I could even have missed out the semicolons after ‘then’
and ‘ else’, because the shell knows that a command must come after each of those — though
the semicolon or newline before the then is often important, because the shell does not
know a command has to come next, and might mix up the then with the arguments of the
command after the ‘if’: it may look odd, but the ‘[[ ... ]]’ is actually a command. So you
will see various ways of dividing up the lines in shell programmes. You might also like to
know that print is one of the builtin commands referred to before; in other words, the whole
of that chunk of programme is executed by the shell itself. If you’re using a newish version
of the shell, you will notice that zsh tells you what it’s waiting for, i.e. a ‘then’ or an ‘else’
clause — see the explanation of $PS2 below for more on this. Finally, the spaces I put before
the ‘print’ commands were simply to make it look prettier; any number of spaces can appear
before, after, or between commands and arguments, as long as there’s at least one between
ordinary words (the semicolon is recognised as special, so you don’t need one before that,
though it’s harmless if you do put one in).
Second aside for users of sh: you may remember that tests in sh used a single pair of
brackets, ‘if [ ... ]; then ...’, or equivalently as a command called test, ‘if test
...; then ...’. The Korn shell was deliberately made to be different, and zsh follows that.
The reason is that ‘[[’ is treated specially, which allows the shell to do some extra checks and
allows more natural syntax. For example, you may know that in sh it’s dangerous to test a
parameter which may be empty: ‘[ $var = foo ]’ will fail if $var is empty, because in that
case the word is missed out and the shell never knows it was supposed to be there; with ‘[[
... ]]’, this is quite safe because the shell is aware there’s a word before the ‘=’, even if it’s
empty. Also, you can use ‘&&’ and ‘||’ to mean logical ‘and’ and ‘or’, which agrees with the
usual UNIX/C convention; in sh, they would have been taken as starting a new command,
not as part of the test, and you have to use the less clear ‘-a’ and ‘-o’. Actually, zsh provides
the old form of test for backward compatibility, but things will work a lot more smoothly if
you don’t use it.
2.2 All the startup files
Now here’s a list of the startup files and when they’re run. You’ll see they fall into two
classes: those in the /etc directory, which are put there by the system administrator and
are run for all users, and those in your home directory, which zsh, like many shells, allows
you to abbreviate to a ‘~’. It’s possible that the latter files are somewhere else; type ‘print
$ZDOTDIR’ and if you get something other than a blank line, or an error message telling you
the parameter isn’t set, it’s telling you a directory other than ‘~’ where your startup files live.
If $ZDOTDIR (another parameter) is not already set, you won’t want to set it without a good
reason.
/etc/zshenv Always run for every zsh.