与非 tty 交互时,如何让 systemctl 以彩色打印?

cro*_*urg 25 linux tty arch-linux watch systemctl

当我运行这样的命令时:

# systemctl status plexmediaserver
Run Code Online (Sandbox Code Playgroud)

我得到漂亮的彩色输出。但是当我运行以下命令时:

# watch -n300 --color systemctl status plexmediaserver
Run Code Online (Sandbox Code Playgroud)

有什么办法可以watch用颜色来执行这个命令systemctl吗?我已经查看了手册页,systemctl但在任何地方都没有看到对颜色的引用。

cro*_*urg 26

systemctl似乎没有指定何时为输出着色的机制。一个快速的解决方案是填充isatty(3)以始终返回 true,从而使人们误systemctl以为 stdout 是交互式的。即你可以这样做:

# 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
Run Code Online (Sandbox Code Playgroud)

所述-xc -在所述的端部gcc命令告诉gcc编译C代码(-xc从标准)( -)。其余的标志告诉gcc创建一个名为isatty.so. 请注意,这很可能会破坏其他依赖于isatty返回合法值的程序。然而,它似乎很好,systemctl因为它isatty似乎仅用于确定是否应该为其输出着色。

  • 在我阅读并投票了 towolf 的答案(比这个好得多)后,我本来打算投反对票,但这是一个太完美的黑客,所以我以某种复杂的感觉投票赞成:) (2认同)

小智 22

watch -c  SYSTEMD_COLORS=1 systemctl status icinga2
Run Code Online (Sandbox Code Playgroud)

man systemd

   $SYSTEMD_COLORS
       Controls whether colorized output should be generated.
Run Code Online (Sandbox Code Playgroud)

即,您可以强制使用颜色模式。


Tom*_*ale 5

根据@KarlC 的回答,这里是一个在运行时生成并包含该库的脚本:

#!/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" "$@"
Run Code Online (Sandbox Code Playgroud)

  • ...真是个黑客 (2认同)