systemctl
no parece tener un mecanismo para especificar cuándo colorear la salida. Una solución rápida sería calzar isatty(3)
para devolver siempre verdadero, engañando así a systemctl
en pensar que stdout es interactivo. Es decir, podrías hacer:
# 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
El -xc -
al final del gcc
el comando le dice a gcc
para compilar código C (-xc
) de la entrada estándar (-
). El resto de banderas dicen gcc
para crear un archivo de objeto compartido llamado isatty.so
. Tenga en cuenta que esto podría romper otros programas que dependen de isatty
para devolver un valor legítimo. Sin embargo, parece estar bien para systemctl
como isatty
parece usarse únicamente con el fin de determinar si debe colorear su salida.
watch -c SYSTEMD_COLORS=1 systemctl status icinga2
man systemd
dice
$SYSTEMD_COLORS
Controls whether colorized output should be generated.
es decir, puede forzar el modo de color con eso.
Basado en la respuesta de @KarlC, aquí hay un script que genera y luego incluye la biblioteca en tiempo de ejecución:
#!/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]"