Wie kann ich in der Ausgabe meines Überwachungsbefehls blättern?

38

Ich verwende den watchBefehl, um zu sehen, wie sich der Inhalt meines Verzeichnisses ändert, während ein Skript darauf ausgeführt wird (über watch ls dir/).

Es ist ein großartiges Werkzeug, außer dass ich nicht nach unten oder oben scrollen kann, um den gesamten Inhalt zu sehen, sobald die Anzahl der Einträge die vertikale Länge des Bildschirms ausfüllt.

Gibt es eine Möglichkeit, dies zu tun?

Zaid
quelle
Es ist topless, aber konnte es nur für BSD oder in rpm, kein Deb-Paket finden
Antony Gibbs

Antworten:

31

watchist großartig, aber dies ist eines der Dinge, die es nicht tun kann. Sie können verwenden tail, um die neuesten Einträge anzuzeigen:

watch "ls -rtx dir/ | tail -n $(($LINES - 2))"
Bis auf weiteres angehalten.
quelle
1
Können Sie erklären, warum es notwendig ist $(($LINES - 2))", um die neuesten Einträge zu erhalten?
bbaja42
6
@ bbaja42: Es füllt den Bildschirm aus und lässt ein paar Zeilen für die Ausgabe von watchsich. $LINESist eine automatische Variable, mit der Bash und andere Shells die Anzahl der Zeilen enthalten, die der Bildschirm anzeigen kann. Sie könnten eine tailbeliebige Nummer, die Sie wollen.
Bis auf weiteres angehalten.
Kann ich den Befehl so verwenden, wie er ist, um die Ausgabe mehrerer Programme (die mit && verkettet wurden) zum Ende zu leiten?
T0xicCode
@ xav0989: Sie müssten Ihre Kette in geschweifte Klammern einwickeln, sonst wird nur tailder letzte Befehl ausgeführt: { command1 && command2 && command3; } | tail- Vergessen Sie nicht die Leerzeichen (nach dem Öffnen und vor dem Schließen der Klammer) und das Semikolon nach dem letzten Befehl. Denken Sie daran, dass die gesamte Kette bei jeder watcherneuten Ausführung ausgeführt wird.
Bis auf weiteres angehalten.
13

Ich habe ein kleines Programm erstellt, das genau das macht, was Sie in Python wollen. Finde es hier , es heißt pwatch.

Joey Yakimowich Payne
quelle
Ich wünschte, es wäre ein heftiger Schlag gewesen!
Inanc Gumus
2

Ich habe ein Bash-Swatch-Programm erstellt, das genau das macht, was Sie in Bash wollen. Im GIF-Video sehen Sie, wie Sie durch eine sich ändernde MMIO-Datei scrollen.

Bildbeschreibung hier eingeben

#!/bin/bash
#
# watch a file and scroll 
#
# keys => arrow-up/down, page-up/down, pos1, end
#
# usages:
#           swatch -n <timeout_watch> <file>
#           swatch <file>
#
# version:          1.1
# dependencies:     awk , tput , clear, read
# published:        https://unix.stackexchange.com/questions/3842/how-can-i-scroll-within-the-output-of-my-watch-command
# gif recording:    peek , https://github.com/phw/peek

#
# =============================================
# KEYCODES
# =============================================
# https://unix.stackexchange.com/questions/294908/read-special-keys-in-bash
# showkey -a


# =============================================
# DEFAULTS
# =============================================
fname=""
line_show_begin=1
line_show_begin_last=-1
console_lines_correction=4
timeout_watch=2
timeout_read=.1


# =============================================
# DEFINE Escape-Sequences
# =============================================

# http://ascii-table.com/ansi-escape-sequences-vt-100.php

ESC_clr_line='\033[K'
ESC_reset_screen='\033c'
ESC_clr_screen='\033[2J'
ESC_cursor_pos='\033[0;0f'
ESC_cursor_home='\033[H'


# =============================================
# FUNCTIONS
# =============================================


function fn_help() {
cat << EOF
Usage: ./$0 [-n <timeout>] [<file>]  ,  timeout >0.1s , default 2s
EOF
}


function get_options() {

    [[ "$1" == "" ]] && { fn_help ; exit 1 ; }

    while [ -n "$1" ]; do

        case "$1" in

        -h|--help) 
            fn_help
            ;;

        -n) 
            [[ "$2" == "" ]] && { echo "Error: option -n required <timeout>" ; exit 1 ; }
            if [[ "$(echo "$2<0.1"|bc)" == "0" ]] ; then 
                timeout_watch="$2" 
                shift
            else
                echo "Error: timeout <0.1 not allowed"
                exit 1
            fi
            ;;

        -*) 
                echo "Error: unknown option »$1«"
                exit 1
            ;;

        *)
            if [[ -f "$1" ]] ; then
                fname=$1
            else
                echo "Error: file not found »$1«"
                exit 1
            fi
            ;;

        esac

        shift

    done

    [[ "$fname" == "" ]] && { echo "Error: file required" ; exit 1 ; }

}


function fn_print_headline() {

    hdl_txt_right="${HOSTNAME}: $(date "+%Y-%m-%d %H:%M:%S")"
    hdl_txt_left="$fname , ${timeout_watch}s , $line_show_begin"

    hdl_txt_left_length=${#hdl_txt_left}

    printf '%s%*s\n\n' "$hdl_txt_left" "$(($console_columns-$hdl_txt_left_length))" "$hdl_txt_right"

}


function fn_print_file() {

    # ---------------------------------------------------
    # file lenght can change while watch
    # ---------------------------------------------------

    lines_fname=$(awk 'END {print NR}' $fname)

    line_last=$(($lines_fname-$console_lines))

    (( "$line_last" < "1" )) && { line_last=1; clear; }

    (( "$line_show_begin" > "$line_last" )) && { line_show_begin=$line_last; clear; }


    # ---------------------------------------------------
    # print postion changed
    # ---------------------------------------------------

    if (( "$line_show_begin" != "$line_show_begin_last" )) ; then

        line_show_begin_last=$line_show_begin;
        clear

    else

        printf $ESC_cursor_home

    fi


    # ---------------------------------------------------
    # print file section
    # ---------------------------------------------------

    fn_print_headline
    awk -v var1="$line_show_begin" -v var2="$console_lines" 'NR>=var1 {if (NR>var1+var2) {exit 0} else {printf "%s\n",$0 } }' $fname

}


function fn_console_size_change() {

    console_columns=$(tput cols)
    console_lines=$(($(tput lines)-$console_lines_correction))
    line_show_begin_last=-1

}


function fn_quit() {

    echo "quit" $0 , $?

    setterm -cursor on ; exit 0

}


# =============================================
# GET OPTIONS
# =============================================

get_options "$@"    # pass all arguments with double-quotes



# =============================================
# INIT TRAP
# =============================================

trap "fn_console_size_change" SIGWINCH # https://en.wikipedia.org/wiki/Signal_(IPC)#SIGWINCH
trap "fn_quit" INT TERM EXIT


# =============================================
# MAIN
# =============================================

fn_console_size_change
setterm -cursor off


while true ; do

    fn_print_file

    read -rsn1 -t $timeout_watch k # char 1

    case "$k" in

    [[:graph:]])
        # Normal input handling
        ;;
    $'\x09') # TAB
        # Routine for selecting current item
        ;;
    $'\x7f') # Back-Space
        # Routine for back-space
        ;;
    $'\x01') # Ctrl+A
        # Routine for ctrl+a
        ;;
    $'\x1b') # ESC

        read -rsn1 k # char 2
        [[ "$k" == ""  ]] && return  Esc-Key
        [[ "$k" == "[" ]] && read -rsn1 -t $timeout_read k # char 3
        [[ "$k" == "O" ]] && read -rsn1 -t $timeout_read k # char 3

        case "$k" in

        A)  # Arrow-Up-Key
            (( "$line_show_begin" > "1" )) && line_show_begin=$(($line_show_begin-1))
            ;;

        B)  # Arrow-Down-Key
            (( "$line_show_begin" < "$line_last" )) && line_show_begin=$(($line_show_begin+1))
            ;;

        H)  # Pos1-Key
            line_show_begin=1
            ;;

        F)  # End-Key
            line_show_begin=$line_last
            ;;

        5)  # PgUp-Key
            read -rsn1 -t $timeout_read k # char 4

            if [[ "$k" == "~" ]] && (( "$line_show_begin" > "$(($console_lines/2))" )) ; then
                line_show_begin=$(($line_show_begin-$console_lines/2))
            else
                line_show_begin=1
            fi
            ;;

        6)  # PgDown-Key
            read -rsn1 -t $timeout_read k # char 4

            if [[ "$k" == "~" ]] && (( "$line_show_begin" < "$(($line_last-$console_lines/2))" )) ; then
                line_show_begin=$(($line_show_begin+$console_lines/2))
            else
                line_show_begin=$line_last
            fi
            ;;

        esac

        read -rsn4 -t $timeout_read    # Try to flush out other sequences ...

        ;;

    esac

done
Bashprogger
quelle
1

Sie könnten watchall Python-Paket verwenden; Die Benutzung ist die gleiche wie bei der Uhr.

sudo pip install watchall
Mohammad
quelle
wird dies herabgestuft, weil die Antwort nicht detailliert genug ist ... oder weil das vorgeschlagene Programm nicht geeignet ist?
RTbecard
1
Ich habe den Teer heruntergeladen. Im Vergleich dazu pwatchsieht es so aus, als würde es -dUnterschiede zwischen Dosen unterstützen watch. Es bindet auch PgUp/ PgDnund unterstützt benutzerdefinierte Intervalle.
Zren