Как заставить systemctl печатать в цвете при взаимодействии с не-tty?

Когда я запускаю такую ​​команду:

# systemctl status plexmediaserver

Я получаю красиво окрашенный вывод. Но когда я запускаю следующую команду:

# watch -n300 --color systemctl status plexmediaserver

Есть ли способ, которым я могу сделать это watch команда с цветом от systemctl? Я посмотрел на странице руководства для systemctl но нигде не вижу ссылки на цвет.

3 ответа

Решение
watch -c  SYSTEMD_COLORS=1 systemctl status icinga2

man systemd говорит

   $SYSTEMD_COLORS
       Controls whether colorized output should be generated.

то есть, вы можете включить цветовой режим с этим.

systemctl по-видимому, не имеет механизма для указания, когда окрашивать вывод. Быстрое решение было бы подложить isatty(3) всегда возвращать истину, таким образом обманывая systemctl в мышление стандартный вывод является интерактивным. А именно вы могли бы сделать:

# 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

-xc - в конце gcc команда говорит gcc скомпилировать код C (-xc) из стандартного ввода (-). Остальные флаги рассказывают gcc создать общий объектный файл с именем isatty.so, Обратите внимание, что это может очень хорошо сломать другие программы, которые полагаются на isatty вернуть законную стоимость. Тем не менее, похоже, что это хорошо для systemctl как isatty кажется, используется исключительно для определения того, должен ли он окрашивать свой вывод.

Основываясь на ответе @KarlC, вот скрипт, который генерирует и затем включает библиотеку во время выполнения:

#!/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" "$@"
Другие вопросы по тегам