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

4433
KarlC

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

# systemctl status plexmediaserver 

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

# watch -n300 --color systemctl status plexmediaserver 

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

14
Пожалуйста, рассмотрите возможность принятия [ответа] Towolf (https://superuser.com/a/1196178/664), который намного лучше, чем принятый в настоящее время (ваш). Заранее спасибо. Piotr Dobrogost 5 лет назад 0

3 ответа на вопрос

23
KarlC

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.

Это великолепно. Я построил [скрипт для автоматизации процесса] (https://superuser.com/a/1245671/365890). Tom Hale 6 лет назад 0
После того, как я прочитал и проголосовал за ответ Towolf (который намного лучше, чем этот), я собирался понизить это, но это слишком совершенный взлом, поэтому вместо этого я голосую с каким-то смешанным чувством :) Piotr Dobrogost 5 лет назад 0
10
towolf
watch -c SYSTEMD_COLORS=1 systemctl status icinga2 

man systemd говорит

 $SYSTEMD_COLORS Controls whether colorized output should be generated. 

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

0
Tom Hale

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

#!/bin/bash set -euo pipefail  function clean_up { trap - EXIT # Restore default handler to avoid recursion [[ -e "$" ]] && 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 "$" -c 'eval $@' - LD_PRELOAD="$isatty_so" "$@" 

Похожие вопросы