22

When I run a command like this:

# systemctl status plexmediaserver

I get nicely colored output. But when I run the following command:

# watch -n300 --color systemctl status plexmediaserver

Is there any way I can do this watch command with color from systemctl? I've looked at the man page for systemctl but do not see reference to color anywhere.

  • Please consider accepting towolf's answer which is much better than currently accepted one (yours). Thank you in advance. – Piotr Dobrogost Jun 19 '18 at 12:37
17
watch -c  SYSTEMD_COLORS=1 systemctl status icinga2

man systemd says

   $SYSTEMD_COLORS
       Controls whether colorized output should be generated.

i.e., you can force color mode with that.

  • … and of course, by now SYSTEMD_COLORS does more than the name suggests, because mid 2018 support for clickable links got introduced, littering output with some escape codes and urlified URLs – which fortunately can be turned off with SYSTEMD_URLIFY=0 – eMPee584 Apr 20 '19 at 11:15
26

systemctl does not appear to have a mechanism for specifying when to color the output. A quick solution would be to shim isatty(3) to always return true, thus tricking systemctl into thinking stdout is interactive. Namely you could do:

# echo "int isatty(int fd) { return 1; }" | gcc -O2 -fpic -shared -ldl -o isatty.so -xc -
# LD_PRELOAD=./isatty.so watch -n300 --color systemctl status plexmediaserver

The -xc - at the end of the gcc command tells gcc to compile C code (-xc) from stdin (-). The rest of the flags tell gcc to create a shared object file named isatty.so. Note that this could very well break other programs which rely on isatty to return a legitimate value. It however appears to be fine for systemctl as isatty appears to be solely used for the purpose of determining if it should color its output.

  • This is brilliant. I built a script to automate the process. – Tom Hale Aug 30 '17 at 6:08
  • 1
    After I read and voted towolf's answer (which is much better than this one) up I was going to downvote this but this is too perfect a hack so instead I'm voting this up with somehow mixed feelings :) – Piotr Dobrogost Jun 19 '18 at 12:35
  • You genius, it works with the clang-tidy color output issue with cmake, brilliant!!! – Sunding Wei Dec 2 '20 at 4:46
3

Based on @KarlC's answer, here is a script which generates and then includes the library at runtime:

#!/bin/bash
set -euo pipefail

function clean_up {
  trap - EXIT # Restore default handler to avoid recursion
  [[ -e "${isatty_so:-}" ]] && rm "$isatty_so"
}
# shellcheck disable=2154 ## err is referenced but not assigned
trap 'err=$?; clean_up; exit $err' EXIT HUP INT TERM

isatty_so=$(mktemp --tmpdir "$(basename "$0")".XXXXX.isatty.so)
echo "int isatty(int fd) { return 1; }" \
  | gcc -O2 -fpic -shared -ldl -o "$isatty_so" -xc -
# Allow user to SH=/bin/zsh faketty mycommand
"${SH:-$SHELL}" -c 'eval $@' - LD_PRELOAD="$isatty_so" "$@"
  • ...what a hack 😅 – eMPee584 Apr 20 '19 at 10:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.