web-dev-qa-db-fra.com

Comment puis-je obtenir SystemCTL pour imprimer de la couleur lorsqu'il est interagi avec un non-TTY?

Quand j'exécute une commande comme ceci:

# systemctl status plexmediaserver

Je reçois une sortie joliment colorée. Mais quand j'exécute la commande suivante:

# watch -n300 --color systemctl status plexmediaserver

Y a-t-il une façon que je puisse faire cette commande watch _ avec la couleur de systemctl? J'ai regardé la page d'homme pour systemctl mais ne vois pas de référence à la couleur nulle part.

19
cronburg

systemctl ne semble pas avoir de mécanisme de spécification de la couleur. Une solution rapide serait de shim isatty(3) _ Pour toujours retourner vrai, trompant ainsi systemctl dans la pensée STDOUT est interactif. À savoir que vous pourriez faire:

# 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

Le -xc - à la fin de la commande gcc _ indique gcc _ pour compiler C code (-xc) de stdin (-). Le reste des drapeaux indique gcc pour créer un fichier d'objet partagé nommé isatty.so. Notez que cela pourrait très bien casser d'autres programmes qui s'appuient sur isatty pour renvoyer une valeur légitime. Cependant, cela semble être bon pour systemctl comme isatty semble être utilisé uniquement dans le but de déterminer s'il doit colorer sa production.

23
cronburg

Basé sur @ Karlc's Reshant , voici un script qui génère puis inclut la bibliothèque au moment de l'exécution:

#!/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" "$@"
2
Tom Hale