我正在尝试运行docker build
命令。我只想连续查看输出的最后“n”行。例如,通常的 docker build 命令给我类似的东西:
Building myimage
Step 1/15 : FROM python:3.6.9
---> 5bf410ee7bb2
Step 2/15 : WORKDIR /
---> Running in 201dd686c5d9
Removing intermediate container 201dd686c5d9
---> 298d3c728059
Step 3/15 : COPY . .
---> a47754a932c3
Step 4/15 : RUN chmod 755 /launch/start-script.sh
---> Running in ef27984abecf
Removing intermediate container ef27984abecf
---> ae13426f44e9
Step 5/15 : RUN pip install --upgrade pip
...
...
...
所需的输出n=3
是
Removing intermediate container ef27984abecf
---> ae13426f44e9
Step 5/15 : RUN pip install --upgrade pip
我试着把它管到尾巴上,
docker build | tail -3
但是一旦构建完成,就会显示最后 3 行。进程运行时是否可以连续显示最后“n”行?
答案1
#!/bin/sh
i=0
[ "$#" = 1 ] || { >&2 echo "The number of lines should be provided"; exit 9; }
nlines=$1
while IFS= read -r line; do
clear
all="$all
$line"
i=$((i+1))
if [ "$i" -ge "$nlines" ]; then
all="${all#*
}"
fi
printf '%s\n' "$all"
done
使其可执行 ( chmod +x nlines.sh
),然后仅连续打印 3 行,
docker build | ./nlines.sh 3
clear
清除屏幕。每当一行来自标准输入时就会执行此操作。这会将新读取的行添加到变量中
all
:
all="$all
$line"
[ "$i" -ge "$nlines" ]
测试是否达到要显示的最大行数。如果是,- 这将从变量中删除最旧的行。
all="${all#*
}"
答案2
我开发了一个用于观看程序输出的实用程序,称为pw
(管表)。
它的基本要点与接受的答案中的 shell 脚本没有太大不同:程序连续读取标准输入中的所有内容,并通过重新定位光标(ANSI 序列)和重新绘制线条来更新显示。
pw
通过一个小的 FIFO 缓冲区泵送线路,该缓冲区根据其所处的模式根据几个不同的规则进行采样。因为它不保留通过它的所有数据,所以程序以少量固定量运行内存。
pw
与 POSIX 作业控制集成。当您将其放在后台并告诉它执行(或在后台启动作业)时,它仍然读取其输入,但不会更新终端显示(这样做会产生信号SIGTTOU
)。在后台操作中,触发器仍在运行,并且会拍摄 FIFO 的快照。当您将其置于前台时,显示内容将被重新绘制。因此,在一个 shell 会话中,您可以同时处理许多可以监视的工作pw
。在后台,它们不会阻塞,因为有东西正在读取它们的输出。
pw
为您提供一堆 grep 模式,您可以即时编辑它们,以便在输入到达 FIFO 之前对其进行过滤。
您可以设置触发器来捕获 FIFO 的快照以供显示。有 19 深的快照历史记录。触发器由与 FIFO 的特定行相匹配的模式组成。如果您使用触发器来锁定重复模式,触发器可以使显示看起来“冻结”,就像示波器的触发如何使周期性波形看起来静止一样。
该视图可以分为两个或三个不同大小和位置的垂直窗格。左窗格显示行的前缀,中间窗格显示任意中间部分,右窗格显示可水平滚动的前缀之后的行的其余部分。
答案3
您可以使用 轻松完成此操作tput
。我创建了一个 zsh 函数,可以在不清除屏幕的情况下跟踪命令的最后 n 行。我仅在运行 MacOS 12.6 Monterey 的 m1 mac 上对此进行了测试。
function tail_lines () {
# save cursor position
tput sc
tput ed
# if is a number
# `<->' is a special zsh pattern to match any number, an extension of forms like `<1-100>' which matches any number in the range 1 to 100 inclusive
# https://zsh.sourceforge.io/Guide/zshguide03.html
if [[ "$1" = <-> ]]; then
nlines=$1
else
nlines=5
fi
YELLOW=$(tput setaf 3)
NORMAL_COLOR=$(tput sgr0)
while IFS= read -r line; do
# restore cursor position
tput rc
if [ -z "$output" ]; then
output=" $line"
else
output=`echo "$output\n $line" | tail -n $nlines`
fi
printf -- "${YELLOW}$output${NORMAL_COLOR}\n"
done < /dev/stdin
tput rc
tput ed || tput 'cd'
}
用法
brew update | tail_lines
或者
brew update | tail_line 10
答案4
尝试
docker build > logfile &
tail -3 -f logfile
-f 可以执行您想要的操作,但它不适用于管道,因此需要中间文件。