systemctl
scheint keinen Mechanismus zum Angeben zu haben, wann die Ausgabe gefärbt werden soll. Eine schnelle Lösung wäre, isatty(3)
zu shimen um immer wahr zurückzugeben, wodurch systemctl
ausgetrickst wird zu denken, dass stdout interaktiv ist. Sie könnten nämlich Folgendes 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
Die -xc -
am Ende von gcc
Befehl sagt gcc
um C-Code zu kompilieren (-xc
) von stdin (-
). Der Rest der Flags sagt gcc
um eine gemeinsam genutzte Objektdatei mit dem Namen isatty.so
zu erstellen . Beachten Sie, dass dies sehr wohl andere Programme beschädigen könnte, die auf isatty
angewiesen sind um einen legitimen Wert zurückzugeben. Für systemctl
scheint es jedoch in Ordnung zu sein als isatty
scheint ausschließlich dazu verwendet zu werden, zu bestimmen, ob die Ausgabe gefärbt werden soll.
watch -c SYSTEMD_COLORS=1 systemctl status icinga2
man systemd
sagt
$SYSTEMD_COLORS
Controls whether colorized output should be generated.
d.h. Sie können damit den Farbmodus erzwingen.
Basierend auf der Antwort von @KarlC ist hier ein Skript, das die Bibliothek zur Laufzeit generiert und dann einbindet:
#!/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 [email protected]' - LD_PRELOAD="$isatty_so" "[email protected]"