You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Linux Shell中实现多行输出原地刷新覆盖?

你之前的代码失效的核心原因是 \r 仅能将光标回退到当前行的行首,而你grep得到的$OUTP变量中自带多行换行符,输出时会自动换行到新行,最终只有最后一行会被\r覆盖,之前的行都会永久保留在终端中,导致内容不断堆叠。

可行解决方案

根据使用场景可以选择以下几种方案:

方案1:直接使用watch命令(最简单,适合独立监控场景)

不需要自己写循环,系统自带的watch命令默认就支持原地刷新内容,直接执行即可:

watch -n 5 'df -h | grep sda'

参数说明:-n 5指定刷新间隔为5秒,命令输出会自动原地刷新,不会有内容残留。

方案2:ANSI转义序列实现(适合嵌入自定义脚本)

通过终端ANSI控制序列手动控制光标位置和旧内容清除,兼容性覆盖绝大多数现代终端:

# 首次输出初始内容
OUTP=$(df -h | grep sda)
echo -e "$OUTP"
# 统计输出行数,用于控制光标上移距离
line_count=$(echo "$OUTP" | wc -l)

# 后续循环刷新
for i in {1..99}; do
  sleep 5
  # 光标上移line_count行,同时清除光标到屏幕末尾的所有旧内容
  echo -ne "\033[${line_count}A\033[J"
  # 输出新内容
  OUTP=$(df -h | grep sda)
  echo -e "$OUTP"
  # 可选:如果sda分区数量可能动态变化,每次刷新后重新统计行数
  line_count=$(echo "$OUTP" | wc -l)
done

方案3:tput命令实现(兼容性更强)

如果需要适配非常老的终端,用tput调用系统terminfo数据库生成控制序列,不需要手动记忆ANSI码:

OUTP=$(df -h | grep sda)
echo -e "$OUTP"
line_count=$(echo "$OUTP" | wc -l)

for i in {1..99}; do
  sleep 5
  # 光标上移line_count行
  tput cuu "$line_count"
  # 清除光标到屏幕结尾的所有内容
  tput ed
  OUTP=$(df -h | grep sda)
  echo -e "$OUTP"
  line_count=$(echo "$OUTP" | wc -l)
done

内容的提问来源于stack exchange,提问作者DenisZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 00:15:06