Shell输入输出(一):echo/printf输出,格式控制与颜色设置

Shell输入输出(一):echo / printf 输出,格式控制与颜色设置

------ 当你的脚本需要"说清楚"发生了什么
"日志不是给机器看的,是给人看的。而人,需要结构、重点和上下文。"

------ 一个被满屏无格式日志逼出强迫症的架构师


凌晨两点,告警响起:电科金仓 KES 备份失败

你 SSH 登录,运行诊断脚本,屏幕上刷出:

复制代码
start
check dir
dir ok
connect db
connected
dump start
error
exit 1

没有时间戳,没有关键路径,没有错误详情。

你只能猜:"error" 是磁盘满?权限错?还是网络断?

那一刻我意识到:输出的质量,决定了排障的速度

今天,我们就把 Shell 的输出这件事讲透------

不是"能不能打出来",而是"怎么让人一眼看懂"。


一、echo vs printf:简单输出 vs 精确控制

工具 优点 缺点 适用场景
echo 简单直接 行为不一致(不同系统 -e 支持不同) 快速调试、简单提示
printf 格式精确、POSIX 标准、可移植 语法稍复杂 正式脚本、结构化输出

最小对比:

bash 复制代码
# echo:够用,但不可靠
echo "备份完成: $file"

# printf:可控,且一致
printf "备份完成: %s\n" "$file"

在跨平台或生产脚本中,优先用 printf


二、格式控制:让输出有结构

运维中最常见的需求:对齐、列宽、数字精度。

示例:KES 实例状态表

你想输出类似这样的表格:

复制代码
实例名       状态     连接数
core         running  128
report       stopped  0
archive      running  5

printf 轻松实现:

bash 复制代码
#!/usr/bin/env bash

printf "%-12s %-10s %s\n" "实例名" "状态" "连接数"
printf "%-12s %-10s %s\n" "----" "----" "----"

for role in core report archive; do
    status=$(sys_ctl -D "/opt/Kingbase/Server/data_$role" status 2>/dev/null | grep -q running && echo "running" || echo "stopped")
    conn_count=$(ksql -d myapp_"$role" -t -A -c "SELECT count(*) FROM sys_stat_activity;" 2>/dev/null || echo "0")
    
    printf "%-12s %-10s %s\n" "$role" "$status" "$conn_count"
done

关键说明:

  • %s:字符串
  • %-12s:左对齐,宽度12
  • %5d:右对齐整数,宽度5
  • \n:换行(printf 不自动加)

这种输出可直接用于监控看板或邮件报告。


三、颜色设置:突出关键信息

人眼对颜色敏感远高于文字。合理使用颜色,能瞬间传递状态。

基础 ANSI 颜色码:

bash 复制代码
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'  # No Color

安全用法(避免污染后续输出):

bash 复制代码
printf "${RED}错误:%s${NC}\n" "无法连接数据库"
printf "${GREEN}[+] %s${NC}\n" "备份成功"
printf "${YELLOW}警告:%s${NC}\n" "磁盘使用率 > 80%"

✅ 必须以 ${NC} 结尾,否则终端会持续着色。

封装成函数,提升可维护性:

bash 复制代码
log_error() { printf "${RED}[-] %s${NC}\\n" "$*"; }
log_info()  { printf "${GREEN}[+] %s${NC}\\n" "$*"; }
log_warn()  { printf "${YELLOW}[!] %s${NC}\\n" "$*"; }

# 使用
log_info "启动 KES 实例"
if ! sys_ctl start; then
    log_error "启动失败,请检查日志"
    exit 1
fi

这样,整个脚本的输出风格统一,且易于全局调整。


四、真实场景:KES 健康检查报告

bash 复制代码
#!/usr/bin/env bash

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

check_instance() {
    local role="$1"
    local data_dir="/opt/Kingbase/Server/data_$role"
    
    if [[ ! -d "$data_dir" ]]; then
        printf "${RED}[%-10s] 数据目录缺失${NC}\n" "$role"
        return 1
    fi

    if sys_ctl -D "$data_dir" status >/dev/null 2>&1; then
        local conn=$(ksql -d "db_$role" -t -A -c "SELECT count(*) FROM sys_stat_activity;" 2>/dev/null || echo "N/A")
        printf "${GREEN}[%-10s] 运行中 (连接: %s)${NC}\n" "$role" "$conn"
    else
        printf "${YELLOW}[%-10s] 已停止${NC}\n" "$role"
    fi
}

echo "=== KES 实例健康状态 ==="
check_instance "core"
check_instance "report"
check_instance "archive"

输出效果:

复制代码
=== KES 实例健康状态 ===
[core      ] 运行中 (连接: 128)
[report    ] 已停止
[archive   ] 运行中 (连接: 5)

绿色表示正常,黄色表示需关注,红色表示故障------一目了然。


五、注意事项

  1. 不要在非终端环境强制着色

    如果脚本输出被重定向到文件,颜色码会变成乱码。可加判断:

    bash 复制代码
    if [ -t 1 ]; then
        # 终端输出,启用颜色
        RED='\033[0;31m'
        NC='\033[0m'
    else
        RED=''
        NC=''
    fi
  2. echo -e 不可移植

    在 BSD(如 macOS)或某些嵌入式 shell 中,echo -e 可能不支持转义。printf 是 POSIX 标准,更可靠。

  3. 避免过度使用颜色

    颜色是信号,不是装饰。只用于状态(成功/警告/错误),不要全文彩色。


结语:输出是脚本的"用户界面"

在自动化运维中,你的脚本可能每天被调用上百次,但人只在出问题时看它

这时候,清晰、结构化、带重点的输出,就是缩短 MTTR(平均修复时间)的关键。

printf 和颜色不是炫技,而是对使用者的尊重

今日实践

写一个函数 print_status(role, status, metric)

根据 status 为 "ok"/"warn"/"err" 输出不同颜色的行,

并用 printf 对齐字段。

做完这个,你的脚本就拥有了"表达力"。


注:文中涉及的 KES(Kingbase Enterprise Server)是由电科金仓开发的企业级关系型数据库,其运维脚本常需生成结构化状态输出。技术背景可参考 产品页面

相关推荐
a程序小傲2 小时前
得物Java面试被问:流批一体架构的实现和状态管理
java·开发语言·数据库·redis·缓存·面试·架构
b***25112 小时前
动力电池点焊工艺解析
运维·自动化
Jess072 小时前
MySQL操作库 —— 库的操作
数据库·mysql
ycydynq2 小时前
django 数据库 单表操作
数据库·oracle·django
qq_12498707533 小时前
基于SpringBoot的闪电队篮球俱乐部管理系统的设计与开发(源码+论文+部署+安装)
java·数据库·spring boot·后端·spring·毕业设计·计算机毕业设计
开开心心_Every3 小时前
PDF转图片工具推荐:免费支持批量转换
linux·运维·服务器·spring boot·edge·pdf·powerpoint
春日见3 小时前
Docker中如何删除镜像
运维·前端·人工智能·驱动开发·算法·docker·容器
仍然.3 小时前
MySQL--数据库基础
数据库·mysql
难得的我们3 小时前
如何为开源Python项目做贡献?
jvm·数据库·python