コマンド出力の最後の n 行を表示します。

コマンド出力の最後の n 行を表示します。

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バッファを介してポンピングされます。通過するすべてのデータは保持されないため、プログラムは小さく固定された量のメモリで動作します。

pwPOSIX ジョブ制御と統合されます。バックグラウンドに置いて実行(またはバックグラウンドでジョブを開始する)を指示しても入力を読みますが、端末ディスプレイを更新しません(そうすると信号が生成されますSIGTTOU)。バックグラウンドジョブでは、トリガーは引き続き実行され、FIFOのスナップショットが作成されます。これを前景に読み込むと、表示内容が再描画されます。したがって、シェルセッション内では、監視できる多くのタスクが同時に進行する可能性がありますpw。後ろでは、何かが出力を読み取っているのでブロックしません。

pwFIFOに到達する前に入力をフィルタリングするためにすぐに編集できるさまざまな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必要に応じて実行されますが、パイプでは機能しないため、中間ファイルが必要です。

関連情報