Comment puis-je faire défiler la sortie de ma commande watch?

38

J'utilise la watchcommande pour voir le contenu de mon répertoire changer au fur et à mesure de l'exécution du script (via watch ls dir/)

C'est un excellent outil, sauf que je n'arrive pas à faire défiler l'écran vers le bas ou le haut pour voir tout le contenu une fois que le nombre d'entrées remplit la longueur verticale de l'écran.

Y a-t-il un moyen de faire cela?

Zaid
la source
il est topless mais ne le trouve que pour bsd ou en rpm, pas de paquet deb
Antony Gibbs

Réponses:

31

watchC'est génial, mais c'est l'une des choses qu'il ne peut pas faire. Vous pouvez utiliser tailpour afficher les dernières entrées:

watch "ls -rtx dir/ | tail -n $(($LINES - 2))"
En pause jusqu'à nouvel ordre.
la source
1
Pouvez-vous expliquer pourquoi il est nécessaire d'utiliser $(($LINES - 2))"pour obtenir les dernières entrées?
bbaja42
6
@ bbaja42: Il remplit l'écran, laissant quelques lignes pour la sortie de watchlui - même. $LINESest une variable automatique utilisée par Bash et d’autres coques pour contenir le nombre de lignes que l’écran peut afficher. Vous pouvez tailn'importe quel nombre que vous voulez.
pause jusqu'à nouvel ordre.
Puis-je utiliser la commande telle quelle pour canaliser la sortie de plusieurs programmes (chaînés avec &&)?
T0xicCode
@ xav0989: Vous devez enrouler votre chaîne entre des accolades, sinon ce sera uniquement tailla dernière commande: { command1 && command2 && command3; } | tail- n'oubliez pas les espaces (après l'ouverture et avant la fermeture) et le point-virgule après la dernière commande. Rappelez-vous que toute la chaîne sera exécutée à chaque nouvelle watchexécution.
pause jusqu'à nouvel ordre.
13

J'ai créé un petit programme qui fait exactement ce que vous voulez en python. Trouvez-le ici , ça s'appelle pwatch.

Joey Yakimowich Payne
la source
Souhait, c'était en bash!
Inanc Gumus
2

J'ai créé un programme bash ** swatch ** qui fait exactement ce que vous voulez dans bash. Dans la vidéo gif, vous pouvez voir comment faire défiler un fichier mmio changeant.

entrez la description de l'image ici

#!/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
la source
1

Vous pouvez utiliser le paquet watchall python; son utilisation est la même que montre.

sudo pip install watchall
Mohammad
la source
cela at-il été voté parce que la réponse n’est pas assez détaillée ... ou parce que le programme proposé n’est pas adapté?
RTbecard
1
J'ai téléchargé le goudron. Par rapport à pwatch, il semble que cela aide -dà se différencier comme watchon peut. Il lie également PgUp/ PgDn, il prend également en charge les intervalles personnalisés.
Zren