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
(チューブメータ)。
基本的なポイントは、許容される回答のシェルスクリプトとは大きく異なりません。プログラムは標準入力のすべてを継続的に読み取り、カーソル位置(ANSIシーケンス)を変更し、線を再描画してディスプレイを更新します。
pw
ラインは、そのモードに応じていくつかの異なる規則に従ってサンプリングされる小さなFIFOバッファを介してポンピングされます。通過するすべてのデータは保持されないため、プログラムは小さく固定された量のメモリで動作します。
pw
POSIX ジョブ制御と統合されます。バックグラウンドに置いて実行(またはバックグラウンドでジョブを開始する)を指示しても入力を読みますが、端末ディスプレイを更新しません(そうすると信号が生成されますSIGTTOU
)。バックグラウンドジョブでは、トリガーは引き続き実行され、FIFOのスナップショットが作成されます。これを前景に読み込むと、表示内容が再描画されます。したがって、シェルセッション内では、監視できる多くのタスクが同時に進行する可能性がありますpw
。後ろでは、何かが出力を読み取っているのでブロックしません。
pw
FIFOに到達する前に入力をフィルタリングするためにすぐに編集できるさまざまなgrepパターンを提供します。
表示するFIFOのスナップショットをキャプチャするようにトリガを設定できます。 19の深いスナップショット記録があります。トリガーは、FIFO の特定の行に一致するパターンで構成されます。トリガを使用して繰り返しパターンを固定する場合、オシロスコープのトリガが周期的な波形を固定されているように見えるように、トリガはディスプレイを「停止」したように見せることができます。
ビューは、サイズと位置が異なる2つまたは3つの垂直ウィンドウに分割できます。左側のペインには行のプレフィックスが表示され、中央のペインには中間部分が表示され、右側のペインには水平方向にスクロールできるプレフィックスの後の残りの行が表示されます。
答え3
を使用すると、簡単にこれを行うことができますtput
。画面をクリアせずにコマンドの最後のn行を追跡するzsh関数を作成しました。私は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必要に応じて実行されますが、パイプでは機能しないため、中間ファイルが必要です。