Bagaimana saya bisa menggulir dalam output perintah arloji saya?

38

Saya menggunakan watchperintah untuk melihat isi direktori saya berubah ketika skrip berjalan di atasnya (via watch ls dir/)

Ini alat yang hebat, kecuali bahwa saya tidak dapat menggulir ke bawah atau ke atas untuk melihat semua konten begitu jumlah entri memenuhi panjang vertikal layar.

Apakah ada cara untuk melakukan ini?

Zaid
sumber
ada topless tetapi hanya bisa menemukannya untuk bsd atau dalam rpm, tidak ada paket deb
Antony Gibbs

Jawaban:

31

watchmemang hebat, tetapi ini adalah salah satu hal yang tidak dapat dilakukannya. Anda dapat menggunakan tailuntuk menampilkan entri terbaru:

watch "ls -rtx dir/ | tail -n $(($LINES - 2))"
Dijeda sampai pemberitahuan lebih lanjut.
sumber
1
Bisakah Anda menjelaskan mengapa itu perlu digunakan $(($LINES - 2))"untuk mendapatkan entri terbaru?
bbaja42
6
@ bbaja42: Ini mengisi layar, meninggalkan beberapa baris untuk output watchitu sendiri. $LINESadalah variabel otomatis yang digunakan Bash dan kerang lainnya untuk memuat jumlah garis yang dapat ditampilkan layar. Anda dapat tailnomor apa pun yang Anda inginkan.
Dijeda sampai pemberitahuan lebih lanjut.
Bisakah saya menggunakan perintah apa adanya untuk menyalurkan output dari beberapa program (dirantai menggunakan &&) ke tail?
T0xicCode
@ xav0989: Anda harus membungkus rantai Anda dengan kurung kurawal atau itu hanya akan tailmenjadi perintah terakhir: { command1 && command2 && command3; } | tail- jangan lupa spasi (setelah membuka dan sebelum menutup kurung) dan titik koma setelah perintah terakhir. Ingat, seluruh rantai akan dieksekusi setiap kali watchmemutarnya kembali.
Dijeda sampai pemberitahuan lebih lanjut.
13

Saya telah membuat program kecil yang melakukan apa yang Anda inginkan dengan python. Temukan di sini , namanya pwatch.

Joey Yakimowich Payne
sumber
Berharap, itu dalam bash!
Inanc Gumus
2

Saya telah membuat program bash ** swatch ** yang melakukan apa yang Anda inginkan dalam bash. Dalam video gif, Anda dapat melihat cara menggulir file mmio yang berubah.

masukkan deskripsi gambar di sini

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

Anda bisa menggunakan paket python watchall ; penggunaannya sama dengan jam tangan.

sudo pip install watchall
Mohammad
sumber
apakah ini diturunkan karena jawabannya tidak cukup rinci ... atau karena program yang diusulkan tidak cocok?
RTbecard
1
Saya mengunduh tar. Dibandingkan dengan pwatch, sepertinya mendukung -duntuk diffing like watchcan. Ini juga mengikat PgUp/ PgDn, juga mendukung interval khusus.
Zren