Come posso stampare systemctl a colori quando interagisco con un non-tty?


19

Quando eseguo un comando come questo:

# systemctl status plexmediaserver

Ottengo un output ben colorato. Ma quando eseguo il seguente comando:

# watch -n300 --color systemctl status plexmediaserver

Esiste un modo per eseguire questo watchcomando con il colore da systemctl? Ho guardato la pagina man per systemctlma non vedo riferimenti al colore da nessuna parte.


Ti preghiamo di considerare di accettare la risposta di towolf che è molto meglio di quella attualmente accettata (la tua). Grazie in anticipo.
Piotr Dobrogost,

Risposte:


17
watch -c  SYSTEMD_COLORS=1 systemctl status icinga2

man systemd dice

   $SYSTEMD_COLORS
       Controls whether colorized output should be generated.

cioè, puoi forzare la modalità colore con quella.


... e ovviamente, ormai SYSTEMD_COLORSfa più di quanto suggerisce il nome, perché a metà 2018 è stato introdotto il supporto per i link cliccabili, sporcando l'output con alcuni codici di escape e URL urlati - che fortunatamente possono essere disattivati ​​conSYSTEMD_URLIFY=0
eMPee584

23

systemctlnon sembra avere un meccanismo per specificare quando colorare l'output. Una soluzione rapida sarebbe quella di evitare isatty(3)di tornare sempre veri, quindi indurre systemctla pensare che stdout sia interattivo. Vale a dire che potresti fare:

# 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

Alla -xc -fine del gcccomando dice gccdi compilare il codice C ( -xc) da stdin ( -). Il resto dei flag indica gccdi creare un file oggetto condiviso denominato isatty.so. Si noti che questo potrebbe benissimo rompere altri programmi che si basano isattyper restituire un valore legittimo. Sembra tuttavia che vada bene systemctlperché isattysembra essere utilizzato esclusivamente allo scopo di determinare se deve colorare il suo output.


È brillante. Ho creato uno script per automatizzare il processo .
Tom Hale,

1
Dopo aver letto e votato la risposta di towolf (che è molto meglio di questa) ho intenzione di sottovalutare questo, ma questo è un trucco troppo perfetto, quindi sto votando questo con sentimenti in qualche modo contrastanti :)
Piotr Dobrogost

2

Basato sulla risposta di @ KarlC , ecco uno script che genera e quindi include la libreria in fase di esecuzione:

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

... che hack 😅
eMPee584,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.