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

19

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

# systemctl status plexmediaserver

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

# watch -n300 --color systemctl status plexmediaserver

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

cronburg
источник
Пожалуйста, подумайте о том, чтобы принять ответ Towolf, который намного лучше, чем принятый в настоящее время (ваш). Заранее спасибо.
Петр Доброгост,

Ответы:

17
watch -c  SYSTEMD_COLORS=1 systemctl status icinga2

man systemd говорит

   $SYSTEMD_COLORS
       Controls whether colorized output should be generated.

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

towolf
источник
... и, конечно же , теперь SYSTEMD_COLORSделает больше , чем предполагает название, потому что в середине 2018 поддержки интерактивных ссылок была введена, выход замусоривания с некоторыми эвакуационными кодами и urlified URL , - которые , к счастью , могут быть отключены сSYSTEMD_URLIFY=0
eMPee584
23

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) из stdin ( -). Остальные флаги говорят gccо создании общего объектного файла с именем isatty.so. Обратите внимание, что это может привести к поломке других программ, которые isattyвозвращают допустимое значение. Это , однако , как представляется , будет хорошо для , systemctlкак isattyпредставляется , будет использоваться исключительно для целей определения , если она должна окрашивать свою продукцию.

cronburg
источник
Это великолепно. Я построил скрипт для автоматизации процесса .
Том Хейл,
1
После того, как я прочитал и проголосовал за ответ Towolf (который намного лучше, чем этот), я собирался понизить это, но это слишком совершенный хак, поэтому вместо этого я голосую с каким-то смешанным чувством :)
Петр Доброгост
2

Основываясь на ответе @ 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" "$@"
Том Хейл
источник
... что за хак 😅
eMPee584