I have spaceship-prompt zsh theme installed which requires a powerline font to be displayed correctly. Therefore I want to disable it in shells that run directly on a tty (which can only use bitmap fonts as far as I know) as opposed to the one run inside a terminal emulator in a DE.

I've tried putting this in my .zshrc:

if [[ -o login ]] ; then

It disables the config from loading on login shells but for some reason when I use su the root shell is also marked as login even though I run it in a terminal emulator (Konsole):

➜ su
n750jv# echo $-

Don't know if it's relevant but I've actually created symlink in /root to my .zshrc so that my configs stay in sync.

Note: If I run echo $- in a tty I get the exact same output: 569XZilms

  • 1
    There's no reason why login shells would run in an environment with different fonts. Did you mean something different instead of “login shell”? Maybe shells that run on a text console, as opposed to shells running in a terminal in a GUI? By the way, su with no options does not run a login shell (but other ways to run it do, for examplesu -), so if you end up with a login shell after su there's something weird in your configuration. Commented Apr 19, 2020 at 17:26
  • @Gilles'SO-stopbeingevil' By login shell I meant the one that runs directly on a tty as opposed to the one run inside a terminal emulator in a DE. Technically they are both using the same shell but I'm trying to prevent zsh from sourcing it's .zshrc if it was launched under a tty and thus can't display the theme correctly. What I don't understand is why in a terminal emulator from the user acount echo $- displays 569XZims (note the absense of the l - login option) and after running su and switching to root account in the same terminal echo $- displays 569XZilms Commented Apr 19, 2020 at 18:55

3 Answers 3


It turns out that you want to know whether certain characters display correctly on the terminal where zsh is running. (By the way this has nothing to do with the type of font: it's about the character encoding, and whether the font includes the characters that you use.)

Use the TERM environment variable to get an idea of what terminal the shell is running in. This is likely to be a decent heuristic for font coverage.

Don't skip your whole .zshrc: most settings make sense no matter where the shell runs, for example aliases, completion, etc. Only change the prompt stuff.

case $TERM in

Alternatively, a good enough heuristic may be whether the terminal uses Unicode or an 8-bit encoding. The locale category LC_CTYPE should be a good heuristic.

case ${(L)LC_ALL:-${LC_CTYPE:-$LANG}} in

This has nothing to do with being a login shell or not. For example, if you log in over SSH, you'll get a login shell, which may be displayed on a text console or in a GUI terminal or some other kind of terminal (or no terminal) depending on where you're logging in from.

  • Thank you! The $TERM environment variable is exactly what I needed! I've slightly modified your solution to simply check if $TERM != linux. The second one, however, doesn't really work on my machine as my Linux console does use en_us.utf-8 encoding, the problem is that Terminus font itself doesn't have support for certain PUA code points used by the theme. Commented Apr 20, 2020 at 19:54

There is no general way to achieve this.

Powerline makes use of characters in the Private Use Area of Unicode. I've seen it come as a surprise, again and again, to Powerline (and "nerd fonts") users to learn that Private Use Area really does mean something that does not work the same everywhere, whose meaning is determined entirely by private arrangement.

There is no standard way to determine what glyphs will be rendered for Private Use Area code points, and what private arrangement is in place. There's no way to determine, other than by actually looking at the glyphs or reading the human-readable doco, that a font will have the non-standard glyphs that Powerline expects.

Moreover, there are bitmap fonts that have the non-standard private Powerline glyphs (e.g. Tamzen). So this cannot in the general case be proxied by whether the terminal is a Kernel Virtual Terminal. A KVT might or might not display the non-standard private Powerline glyphs.

Nor can it sensibly be proxied by whether a shell is a login shell. Shells can be login shells on terminal emulators where the fonts have the non-standard private Powerline glyphs (several GUI terminal emulators having the ability to start shells as login shells), as easily as shells can be non-login shells on terminal emulators where the fonts do not have the non-standard private Powerline glyphs (as one can just fork+exec a child shell, or "shell out" from the likes of mailx or vi).

You simply have to come up with your own private arrangement. Find some way to mark the terminal login sessions where you have (not) installed this particular meaning for Private Use Area code points. Examples of the sorts of ways that this can be achieved:

  • Set an environment variable of your own devising in getty, login, or even the login services for KVT login, and key your shell initialization scripts off that (with the proviso that you need to have administrator access and that you need to maintain this setting in the future as things change).
  • Key off the terminal device file name, in some private way (with the proviso that this is significantly complicated when you introduce real terminals, over serial connections, into the mix; or introduce SSH).
  • Send an ␅ (U+0005) character and key off what comes back (with the proviso that this has always been user-programmable at the terminal end and may indeed not cause anything to come back).

On the gripping hand …

Of course, the better route is to make your theme use standard characters, and not worry about any of these bodges.

There is no actual need for a Private Use Area code point, as the author of your theme supposes, for a locked padlock. That's standardized at U+1F512 (🔒). There's an unlocked padlock at U+1F513 (🔓).

Maybe this PUA thing will turn out to be a turn-of-the-century fad, and people will return to using U+131B1 (𓆱) for a branch once more. ☺

  • Thank you for in depth explanation of Powerline fonts! Learning new things every day... ) Commented Apr 20, 2020 at 20:39

I found the problem: I forgot that I aliased su as su -l myself... :D

edit: As suggested by @Gilles I've modified my config to check the contents of the $TERM environment variable and only load the theme if it's not a Linux console.

if test "$TERM" != "linux"
    autoload -U promptinit; promptinit
    prompt spaceship

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .