27

I have this program that can run with both a text user interface and a graphical user interface.

It lacks any command line switch to force one or the other, rather I guess it somehow auto-detects whether we are in X or not (e.g. if I run it from a virtual terminal it enters its text mode, and if I run it from an X terminal emulator it opens a separate graphical window).

I'd like to force it into text mode and have it run inside the X terminal. How would I go about doing it?

mike3996
  • 1,549

2 Answers2

40

Usually just

unset DISPLAY

in command-line of the terminal. Some applications are smarter than that, and actually check permissions and type of the console versus pseudoterminal.

Thomas Dickey
  • 76,765
  • 7
    Unfortunately, some really obstinate software will assume DISPLAY=:0 if it's unset. I believe you can fix that by running it under a different user and using iptables to drop loopback X11, but that's pretty gross. – Kevin Oct 21 '18 at 19:21
  • 2
    @Kevin maybe DISPLAY=invalid:0 ? – sourcejedi Oct 21 '18 at 19:57
  • no... that would only try to make the program connect to the display on "invalid". It might not timeout rapidly enough to be useful. – Thomas Dickey Oct 21 '18 at 20:36
  • @ThomasDickey fite me :-). There are two X libraries, and the old one was migrated to be a wrapper for the new low-level one. At least on my machine, xterm knows to fail near-instantly on NXDOMAIN. – sourcejedi Oct 21 '18 at 23:18
  • If you don't want to leave DISPLAY unset in that shell, you could do (unset DISPLAY; emacs foo.c) to do the unset in a subshell for one command or list of commands. – Peter Cordes Oct 22 '18 at 06:52
  • 2
    @PeterCordes or you can execute the command through env instead of a subshell: env -u DISPLAY emacs foo.c – pabouk - Ukraine stay strong Oct 22 '18 at 11:19
  • 2
    @PeterCordes emacs does have a command line flag to disable the use of X. Just type emacs -nw. But if it didn't, you could instead use DISPLAY= emacs, which works as well. – kasperd Oct 22 '18 at 11:34
  • 2
    DISPLAY=0.0.0.0:0 fails instantly without doing a name server lookup. – pts Oct 22 '18 at 12:08
  • You could also do something like DISPLAY=:6 if you have problematic software, assuming that display doesn't exist locally. – Julian Goldsmith Oct 22 '18 at 15:13
  • 1
    @Kevin "... and using iptables to drop loopback X11" - No firewalling required; Xorg/XFree86 have been configured not to listen on the network by default for more than ten years on most distributions. It's all done through Unix Domain Sockets (typically something like /tmp/.X11-unix/X0). – marcelm Oct 22 '18 at 18:30
31

If you want to disable X for a single command you can write

DISPLAY= ./my_command

Notice the strategical blank space after =. More generally, you can set environment variables for a process by prefixing your command with a sequence of <variable>=<value> separated by spaces. Since space serves as separator, = immediately followed by a space clears the preceding variable. We can look at the effect of these prefixes by using a subshell as the command and then printing its environment. Take for instance:

$ A=a B=b C= D=d sh
$ echo $A $B $C $D

This will print

a b d

This shows that the environment of the subshell indeed is different as intended. Note that shell substitution happens before the individual arguments are passed to echo. This means that echo will be called with three arguments and so there's only a single space between b and d in the output, just as if the command line were echo a b d (even though there are two spaces before d it only prints single spaces), but unlike echo a b "" d (which prints two spaces between b and d).

tobi_s
  • 391