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

14

Quando eu executo um comando assim:

# systemctl status plexmediaserver

Eu recebo uma saída bem colorida. Mas quando eu corro o seguinte comando:

# watch -n300 --color systemctl status plexmediaserver

Existe alguma maneira de fazer esse comando watch com cor de systemctl ? Eu olhei para a página de manual para systemctl , mas não vejo referência para colorir em qualquer lugar.

    
por KarlC 17.02.2016 / 20:34

3 respostas

10
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.

    
por 06.04.2017 / 18:58
23

systemctl parece não ter um mecanismo para especificar quando colorir a saída. Uma solução rápida seria shim isatty(3) para sempre retornar true, enganando systemctl para pensar 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 comando -xc - no final do comando gcc informa ao gcc para compilar o código C ( -xc ) do stdin ( - ). O restante dos sinalizadores informam gcc para criar um arquivo de objeto compartilhado chamado isatty.so . Observe que isso pode muito bem quebrar outros programas que dependem de isatty para retornar um valor legítimo. No entanto, parece estar bem para systemctl , pois isatty parece ser usado apenas para o propósito de determinar se deve colorir sua saída.

    
por 17.02.2016 / 20:34
0

Com base na resposta do @ 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" "$@"
    
por 30.08.2017 / 08:07