Wie bringe ich systemctl dazu, in Farbe zu drucken, wenn ich mit einem Nicht-Tty interagiere?

19

Wenn ich einen Befehl wie diesen ausführe:

# systemctl status plexmediaserver

Ich bekomme eine schön gefärbte Ausgabe. Aber wenn ich den folgenden Befehl ausführen:

# watch -n300 --color systemctl status plexmediaserver

Gibt es eine Möglichkeit, wie ich diesen watchBefehl mit Farbe ausführen kann systemctl? Ich habe die Manpage nachgesehen, sehe systemctlaber nirgendwo einen Farbbezug.

Cronburg
quelle
Bitte erwägen Sie, die Antwort von towolf zu akzeptieren , die viel besser ist als die derzeit akzeptierte (Ihre). Danke im Voraus.
Piotr Dobrogost

Antworten:

17
watch -c  SYSTEMD_COLORS=1 systemctl status icinga2

man systemd sagt

   $SYSTEMD_COLORS
       Controls whether colorized output should be generated.

Das heißt, Sie können den Farbmodus damit erzwingen.

Towolf
quelle
... und natürlich, jetzt SYSTEMD_COLORStut mehr als der Name bekommt, weil Mitte 2018 die Unterstützung für anklickbare Links eingeführt schon sagt, mit einigem Escape - Codes Littering Ausgang und urlified URLs - die zum Glück mit werden können ausgeschaltetSYSTEMD_URLIFY=0
eMPee584
23

systemctlscheint nicht über einen Mechanismus zu verfügen, mit dem angegeben werden kann, wann die Ausgabe eingefärbt werden soll. Eine schnelle Lösung wäre, zu shimen, isatty(3)um immer wahr zurückzukehren, und so zu täuschen, systemctldass stdout interaktiv ist. Sie könnten nämlich tun:

# 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

Am -xc -Ende des gccBefehls wird angegeben gcc, dass C-Code ( -xc) aus stdin ( -) kompiliert werden soll . Die restlichen Flags geben gccan, dass eine gemeinsam genutzte Objektdatei mit dem Namen erstellt werden soll isatty.so. Beachten Sie, dass dies sehr gut andere Programme beschädigen kann, die darauf angewiesen sind isatty, einen legitimen Wert zurückzugeben. Es scheint jedoch in Ordnung zu sein, systemctlda es isattyanscheinend nur dazu verwendet wird, um zu bestimmen, ob es seine Ausgabe färben soll.

Cronburg
quelle
Das ist brilliant. Ich habe ein Skript erstellt, um den Prozess zu automatisieren .
Tom Hale
1
Nachdem ich Towolfs Antwort (die viel besser ist als diese) gelesen und abgestimmt hatte, wollte ich sie ablehnen, aber das ist ein zu perfekter Hack. Stattdessen stimme ich mit gemischten Gefühlen ab :)
Piotr Dobrogost
2

Basierend auf der Antwort von @ KarlC ist hier ein Skript, das die Bibliothek zur Laufzeit generiert und dann einschließt:

#!/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" "$@"
Tom Hale
quelle
... was für ein Hack?
eMPee584