Como faço para o systemctl imprimir em cores ao interagir com um não-tty?


19

Quando executo um comando como este:

# systemctl status plexmediaserver

Recebo impressões bem coloridas. Mas quando eu executo o seguinte comando:

# watch -n300 --color systemctl status plexmediaserver

Existe alguma maneira de executar esse watchcomando com cores systemctl? Examinei a página de manual, systemctlmas não vejo referência a cores em nenhum lugar.


Por favor, considere aceitar a resposta de towolf, que é muito melhor do que a atualmente aceita (sua). Agradeço antecipadamente.
Piotr Dobrogost

Respostas:


17
watch -c  SYSTEMD_COLORS=1 systemctl status icinga2

man systemd diz

   $SYSTEMD_COLORS
       Controls whether colorized output should be generated.

ou seja, você pode forçar o modo de cores com isso.


... e, claro, agora SYSTEMD_COLORSfaz mais do que o nome sugere, porque meados 2018 suporte para links clicáveis foi introduzido, a saída de lixo com alguns códigos de escape e URLs urlified - que felizmente pode ser desligado comSYSTEMD_URLIFY=0
eMPee584

23

systemctlparece não ter um mecanismo para especificar quando colorir a saída. Uma solução rápida seria calçar isatty(3)para sempre retornar verdadeiro, enganando-se assim, systemctlpensando que stdout é interativo. Ou seja, você poderia fazer:

# 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

O -xc -no final do gcccomando diz gccpara compilar o código C ( -xc) a partir de stdin ( -). O restante dos sinalizadores informa gccpara criar um arquivo de objeto compartilhado chamado isatty.so. Observe que isso pode muito bem interromper outros programas que dependem isattypara retornar um valor legítimo. No entanto, parece estar bem, systemctlpois isattyparece ser usado apenas com o objetivo de determinar se deve colorir sua saída.


Isto é brilhante. Criei um script para automatizar o processo .
Tom Hale

11
Depois de ler e votar na resposta de towolf (que é muito melhor que essa), eu iria votar abaixo, mas isso é um hack muito perfeito, então, em vez disso
votei

2

Com base na resposta de @ KarlC , aqui está um script que gera e inclui a biblioteca em tempo de execução:

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

... o que um hack 😅
eMPee584
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.