How to change background color of FreeBSD terminal

Hi all,

I am not able to find out the exact solution of how can I change the background color of the FreeBSD terminal. I wanted to know if there is any command (similar to setterm in linux) in FreeBSD by which we can change background/foreground terminal colors.

Any alternative of the following would be helpful.
setterm -term linux -back red -fore white -clear rest
 
These are compile-time options only. See vt(4).

Code:
DRIVER CONFIGURATION
   Kernel Configuration Options
     These kernel options control the vt driver.

     TERMINAL_NORM_ATTR=attribute

     TERMINAL_KERN_ATTR=attribute
              These options change the default colors used for normal and
              kernel text.  Available colors are defined in <sys/terminal.h>.
              See EXAMPLES below.

You can also try vidcontrol(1) but I'm not sure if this feature works for vt(4), it used to work for sc(4):
Code:
     foreground [background]
             Change colors when displaying text.  Specify the foreground color
             (e.g. "vidcontrol white"), or both a foreground and background
             colors (e.g. "vidcontrol yellow blue").  Use the show command
             below to see available colors.

 
There are tunables to change the RGB values (red / green /blue components) of the palette entries, see the vt(4) manual page. You can put these into /boot/loader.conf. They take effect upon the next reboot. For example, the following will change the black background color to red:
kern.vt.color.0.rgb="#ff0000"
(I think this works only when vt is used in graphics mode, but not in VGA text mode. I haven't tried this, though, because I rarely ever use the vt text console.)
 
Wait a second … Don't the cons25 compatibility control sequences work with vt(4), too? In that case, you can easily change the default foreground and background colors on the fly, without rebooting or anything. The following shell command would change the default background color to red:
echo -n $'\e[=4G'
In the above control sequence, “4” is red (you can use numbers 0 to 15). Use “F” instead of “G” to change the default foreground color.

To do that automatically after boot, you can create an rc(8) script, e. g. /usr/local/etc/rc.d/default_colors. Within that script, note that you should redirect the echo command to the appropriate terminal device. For example, to handle the first virtual terminal:
echo -n $'\e[=4G' > /dev/ttyv0
You can change all terminals at once with a shell loop. The following would be a complete rc(8) script. Make sure you make it executable ( chmod 755).
Code:
#!/bin/sh

# PROVIDE: default_colors
# REQUIRE: LOGIN

for TTYDEV in /dev/ttyv* ; do
        echo -n $'\e[=4G' > $TTYDEV
done
If you want the change to happen earlier in the boot process, you must put the rc(8) script in /etc/rc.d (because /usr/local is not available that early during boot), remove the “REQUIRE: LOGIN” line, and instead put the following right after the “PROVIDE” line:
# BEFORE: disks
If you do that, your rc script will be the very first one executed during boot, right after the kernel has passed control to init(8).
 
So this FreeBSD machine is running as an instance on the cloud. Is it possible to apply the above solution when I do ssh from one FreeBSD host to other FreeBSD host?
Thanks.
 
So this FreeBSD machine is running as an instance on the cloud. Is it possible to apply the above solution when I do ssh from one FreeBSD host to other FreeBSD host?
So you're connecting with ssh from an xterm (or putty, or whatever)? In that case you don't see the system console at all, why do you want to change its color?
 
  • Like
Reactions: cy@
So, I manage a lot of servers and I want to distinguish FreeBSD instance. I was able to change the color of my terminal while I ssh from local to any FreeBSD instance. However, the solution doesn't work when I ssh from one FreeBSD host to another. Is there any way to solve this problem?

For instance, in Linux, a command named "setterm" would serve the purpose. Is there something similar in FreeBSD?
 
There is no such tool to globally change terminal looks in FreeBSD.
You have to know how to do it for every terminal type you are using.

A remote shell will of course have the looks from the shell configuration of the remote machine.

Why not just change the color of the prompt to a different color?
I do that from my ~/.cshrc - check the hostname and change the prompt color accordingly.
You got to have that in ~/.cshrc (for /bin/csh) on all remote machines.
(use your preferred shell of course)

You can use controll characters like olli@ suggested to create all kinds of color combination fg/bg.
 
So, I manage a lot of servers and I want to distinguish FreeBSD instance. I was able to change the color of my terminal while I ssh from local to any FreeBSD instance. However, the solution doesn't work when I ssh from one FreeBSD host to another. Is there any way to solve this problem?
Oh, ok, so you're not talking about FreeBSD's virtual console terminals at all. So please ignore all of the answers above.

For instance, in Linux, a command named "setterm" would serve the purpose. Is there something similar in FreeBSD?
Linux' setterm command is basically the same as tput(1), just with different syntax. With tput(1) you can change any attributes supported by your terminal, as long as the TERM environment variable is set correctly and the capability is supported by the termcap / terminfo entry.

So, basically the question is: What terminal are you using? xterm, rxvt, putty, whatever … And: Is your TERM environment variable set correctly?

For example, when using xterm (or compatible), you can use this command:
Code:
tput AB 1 AF 7 cd
That command does exactly the same as the setterm command that you quoted in your first post: “AB” sets the background color (1 is red), “AF” sets the foreground color (7 is white), “cd” (clear down) clears the screen from the cursor position down to the end of the screen. Important: The capability shortcuts (AB, AF, cd) are case-sensitive, so be sure to write them exactly as specified.

Most terminal emulators for X11 support a standard palette of 256 colors. In order to be able to use them like above with tput(1), you must set TERM to xterm-256color (or whatever is appropriate for the terminal software that you are using). Here's a useful little script called “ansitest” that displays all the colors with their numbers:
http://inof.de/FreeBSD/scripts/ansitest/
 
Not too long ago I tested a whole bunch of terminal emulators, because I wanted to find out if there's a better one than xterm. During my tests I tried the following: xterm, mlterm, eterm, xvt, rxvt, urxvt, materm, roxterm and konsole. There are more in the Ports Collection, but I didn't try the others because after reading their descriptions it was clear to me that they're out of the question.

Of those, I actually liked mlterm the best. It has a lot of features, and it is easily configurable: Ctrl + right mouse button opens an extensive dialog window, unlike xterm where most changes require editing Xresources and restarting xterm. It even supports proportional fonts (I tried “DejaVu Sans”) – that works surprisingly well, even though output from tools like ls(1), df(1) etc. doesn't line up. On the other hand, manual pages look very beautiful with proportional fonts, almost like a PDF. Also, mlterm has a rather low number of dependencies.

I also liked konsole, if only for the fact that it supports almost all of the monochrome attributes (bold, underline, inverse, …) including double width and double height. No other terminal emulator did that, except for putty and mintty, but putty cannot be used for local sessions (although you can ssh to localhost, of course), and mintty doesn't run on FreeBSD. On the other hand, konsole has a huge number of dependencies (more than 200).

All the others I have tried are inferior to xterm and mlterm, for one reason or another. Some didn't support UTF-8 too well (or not at all), some only supported bitmap fonts without antialiasing, some had problems with copy&paste, and so on. I'm still sticking to xterm for now, but might migrate to mlterm in the future (with monospace fonts, though, because some things – e. g. text editors – don't work very well with proportional fonts, unfortunately).

Shortly after my tests I stumbled across the kitty terminal emulator. I missed it during my tests because it's not in the Ports Collection, but it should be fairly easy to build manually. According to the description on the website, it should also work very well, probably comparable to mlterm, and it even supports very unusual attributes like dotted underline or colored wavy underline and things like that. It also has an API written in Python, so you can easily create extensions and plugins if you're familiar with it (would be a perfect fit for me because I like Python very much). I'll certainly give it a try as soon as I have a little time to spare.

By the way, some of the terminal emulators support tabs and/or (sub)windows for multiple sessions (for example, kitty, mlterm and roxterm do), but I don't need such a feature so I didn't take it into account during my tests. Using several separate terminal windows is the way I'm used to work (optionally with the addition of multiple screen(1) sessions within one xterm), and that's perfectly fine for me, even with a very large number of windows.
 
olli@
Thanks a lot. This is exactly what I wanted. Could you please tell me the tput command to set the terminal background permanently red? I would be so grateful.
 
I wonder if it's possible that the server set a given color to each terminal connected to it (the same color I mean). I think the server should issuing a tput command automatically at each connection. Is it possible to do that (sshd, login...)?
 
I wonder if it's possible that the server set a given color to each terminal connected to it (the same color I mean). I think the server should issuing a tput command automatically at each connection. Is it possible to do that (sshd, login...)?
You could put such a command in your shell profile on that server. For the standard shell sh(1) that would be .profile in your home directory, for example. You can also do it globally in /etc/profile, but it's usually not a good idea to force things like that onto all users, and of course it also depends on the login shell of the user.
 
Thanks. I'm the only user, so I think nobody will complain. ;)
I have only one user who can connect by ssh, I will try this idea in pratice to see if it suits my needs.

I've already done some howlers believing typed in a local console while it was a ssh session with my server.
 
My default shell is /bin/sh. When I start konsole from the KDE desktop, it only runs .shrc. When I login at a virtual terminal or via ssh, it runs /etc/profile, .profile, and .shrc in that order. So since I use konsole often, I put my customizations in .shrc.

I can't test this right now, but IIRC, the /usr/local/bin/bash shell shows the same behavior with konsole and its own remote control file, which is named .bashrc. I can't test this right now either, but if I remember right, the mate-terminal terminal emulator program in the MATE desktop also skips over /etc/profile and .profile.
 
Thank you so much olli@. Your solution works like a charm!. Is tput command documented in any FreeBSD documentation? I could not find in FreeBSD manual page.
 
tput command documented in any FreeBSD documentation? I could not find in FreeBSD manual page.
The command itself is documented in the tput(1) manual page. The termcap capabilities (i. e. those two-character abbreviations that you can use with tput on FreeBSD) are listed in the termcap(5) manual page (although the description is somewhat terse, because it assumes a basic understanding of how termcap works in general). Note that not all of them are supported. The ones that are supported are defined by the entry in /etc/termcap according to the setting of your TERM environment variable.
 
My default shell is /bin/sh. When I start konsole from the KDE desktop, it only runs .shrc. When I login at a virtual terminal or via ssh, it runs /etc/profile, .profile, and .shrc in that order. So since I use konsole often, I put my customizations in .shrc.
That's because .profile is only executed if the shell is a login shell. You should be able to configure konsole to call your shell as a login shell – for example, in the case of xterm, this would be the -ls command line option.

Shells differentiate three cases:
  • Login shells (usually interactive)
  • Interactive shells (whether login or not)
  • Non-interactive shells (e. g. for running scripts, scp and things like that)
The startup scripts that are run in those cases are usually different. For example, FreeBSD's /bin/sh executes .profile only for login shells, and .shrc for every interactive shell (unless overridden via $ENV).

Note that you must take special care when writing startup scripts that are executed for non-interactive shells. First, these startup scripts should produce no output under any circumstances (except on the standard error stream), because that would confuse things like scp(1) and other software that calls shells in an automated way and tries to make sense of the output. Second, there might be a performance bottleneck because the script is executed for every single shell script called, and this can be really a lot, for example when building ports (a configure script alone calls several thousand shells and subshells). And third, your settings can have unpredictable side-effects. For example, if you change the PATH variable to contain your personal $HOME/bin directory at the front, and there happens to be an executable that has the same name as another one in the standard binary directories, things are going to break.

Bottom line: Do not use startup scripts for non-interactive shells, unless you know exactly what you're doing and what the implications are.

I can't test this right now, but IIRC, the /usr/local/bin/bash shell shows the same behavior with konsole and its own remote control file, which is named .bashrc. I can't test this right now either, but if I remember right, the mate-terminal terminal emulator program in the MATE desktop also skips over /etc/profile and .profile.

It is documented in the respective shell's manual page which startup files are used under which circumstances. Usually this is explained near the beginning of the manual page, see sh(1), zsh(1) or bash(1), for example.
 
You could put such a command in your shell profile on that server. For the standard shell sh(1) that would be .profile in your home directory, for example. You can also do it globally in /etc/profile, but it's usually not a good idea to force things like that onto all users, and of course it also depends on the login shell of the user.
I tried and it's exactly what I wanted. But it lacked the terminal returns at its initial colors when the ssh session is ended.

For /bin/sh, I did add in ~/.profile:
trap '. $HOME/.logout' 0
trap 'tput AB 6 AF 1 cd' CHLD


Created ~/.logout with this line inside:
trap '' CHLD
tput op cd


And that works at first glance.

Edit: code updated to make the colors remain after running a program that changes them ( ee, vi, ls -G, etc.).
 
That's because .profile is only executed if the shell is a login shell. You should be able to configure konsole to call your shell as a login shell – for example, in the case of xterm, this would be the -ls command line option.

Shells differentiate three cases:
  • Login shells (usually interactive)
  • Interactive shells (whether login or not)
  • Non-interactive shells (e. g. for running scripts, scp and things like that)
The startup scripts that are run in those cases are usually different. For example, FreeBSD's /bin/sh executes .profile only for login shells, and .shrc for every interactive shell (unless overridden via $ENV).

Note that you must take special care when writing startup scripts that are executed for non-interactive shells. First, these startup scripts should produce no output under any circumstances (except on the standard error stream), because that would confuse things like scp(1) and other software that calls shells in an automated way and tries to make sense of the output. Second, there might be a performance bottleneck because the script is executed for every single shell script called, and this can be really a lot, for example when building ports (a configure script alone calls several thousand shells and subshells). And third, your settings can have unpredictable side-effects. For example, if you change the PATH variable to contain your personal $HOME/bin directory at the front, and there happens to be an executable that has the same name as another one in the standard binary directories, things are going to break.

Bottom line: Do not use startup scripts for non-interactive shells, unless you know exactly what you're doing and what the implications are.



It is documented in the respective shell's manual page which startup files are used under which circumstances. Usually this is explained near the beginning of the manual page, see sh(1), zsh(1) or bash(1), for example.
Thanks, olli@, I'll amend my practices according to your advice ASAP. I appreciate the depth of understanding and study you put into your posts, whereas my own understanding tends to be more observational and reactive. My profile customizations don't produce any output, and are limited to manipulations of environment variables. I would never put any of my custom paths in the front of the PATH environment variable for the exact reason you stated. It might be worth mentioning that I've abandoned the use of the name $HOME/bin as the name of my personal executable directory ever since I discovered that some flavors of GNU/Linux will detect this presence of this directory, and if found, put the $HOME/bin directory into the PATH variable automatically. Although I'm pretty much FreeBSD-only nowadays, I still try to write my scripts in a cross-platform compatible way, and these days I still make the effort to maintain compatibility with Debian. Before deciding on the name of a new interactive script or program, I use the which command to check and see if the name is already in use, and if so, choose a different name. Since the same name might still turn up elsewhere eventually, I've more recently adopted the practice of prefixing the custom executable's name with the name of the custom software package to which it belongs -- even though it may take longer to type, it still seems useful in that it helps to further insure the long-term uniqueness of the name in the face of ever-changing software environments.
 
I'd like to know how to change foreground & background colours simultaneously on /dev/ttyv* (and optionally save setting) on FreeBSD 13.n but I pasted the output of that command below.
[...]
echo -n $'\e[=4G' > /dev/ttyv0
[...]

illegal variable name.
 
What is your shell? Some shells will interpret the $ sign as the start of a variable name.

To make it easier, try typing this from the shell command line: echo "blank control-V Escape [=4G", where blank is the space bar, control-V means control and letter V, Escape is the escape key, and the final "[=4G" are typed as normal characters. That should send the correct character sequence to the screen. Once you have that, work out the correct echo sequence to get it to work in your shell. Personally, I would use
Code:
echo -e "\e[=4G"
(where the \e is entered as two characters, backslash and e), but every shell and every echo command is different.
 
What is your shell? Some shells will interpret the $ sign as the start of a variable name. [...]
I just use default csh.
To make it easier, try typing this from the shell command line: echo "blank control-V Escape [=4G", where blank is the space bar, control-V means control and letter V, Escape is the escape key, and the final "[=4G" are typed as normal characters. [...]
That worked for background only but I know there was an easier/quicker way to do it for foreground & background simultaneously (without setting it at boot time).
echo -e "\e[=4G"
Seems echo doesn't have '-e' argument/flag/switch so echoes '-e "\e[=4G"' literally.
 
Back
Top