Domanda

Per prima cosa, lasciatemi dire che questo è un di programmazione domanda (e quindi non appartiene a superutente et. Al. ) perché sto parlando programmazione della shell. Questo potrebbe quasi essere una domanda di golf, ma non ho una risposta per cominciare, in modo che qualsiasi aiuto sarebbe apprezzato: -)

Quindi, la storia è: mi piace roba tubo nel less con l'opzione --quit-if-one-screen perché è molto confortevole: lessdoes non si ottiene a modo mio, quando non necessaria. O lo fa? Quando il mio prompt è già in fondo alla mia finestra di terminale, questa opzione fa esattamente quello che voglio (vale a dire less si comporta come cat). Ma, quando la mia richiesta corrente è alla parte superiore della finestra, less prima stampe un sacco di righe vuote a trasparente dello schermo, quindi stampa il mio file (breve) nella parte inferiore dello schermo, e solo allora si rende conto che c'è meno il testo di una schermata, così esce e ottengo il mio prompt di schiena.

Ma questo comportamento non è grande, perché di tutte quelle inutili righe vuote. Ho provato diverse opzioni, o scritto gli script e gli alias, e il meglio che potevo venire con sarebbe questo (sto usando zsh, in modo che la Shell è già in grado di duplicare tubi e così via):

function catless() {
 cat   \
  >>( bucket -$LINES | cat  ) \
  >>( bucket +$LINES | less )
}

Dove bucket è un altro script che ho appena scritto, che copia stdin per stdout se si tratta di meno di N righe (con -N) o più di n (con + N). Ho postato qui: http: // Questo esempio vi .net / Gyom / copia-stdin-to-stdout-o-non-seconda-on-length

E ls | catless quasi fabbrica. Ma, per ragioni di sincronizzazione, i diversi processi coinvolti qui non ottengono l'accesso al terminale in modo corretto e tutto viene eseguito in background (in particolare, non ho mai ottenere una corretta less qui, e la richiesta ritorna troppo presto). Ma forse ho preso la strada sbagliata.

Quindi, per riassumere, quello che voglio è tale una funzione / script / qualunque cosa che posso digitare ls | catless e si comporta esattamente come ls | cat quando l'uscita del ls è più breve di uno schermo, e come ls | less quando più.

Tutte le idee?

È stato utile?

Soluzione

notizia per i meno la versione 406 , vedo “Don' t mossa verso il basso dello schermo del prima pagina.”. Quale versione avete? La mia versione del sistema è 382 e si muove verso il basso dello schermo prima della stampa (causando righe vuote se c'è solo una schermata e -F viene utilizzato).

Ho appena installato la versione 436, e sembra di fare ciò che si vuole quando somministrato -FX (metterlo nella LESS env var con le altre preferenze per lasciare qualcosa di utilizzare tali preferenze da solo in esecuzione less).

Se non è possibile ottenere la nuova versione, si potrebbe provare questo, invece:

function catless() {
    local line buffer='' num=0 limit=$LINES
    while IFS='' read -r line; do
        buffer="$buffer$line"$'\n'
        line=''
        num=$(( num+1 ))
        [[ $num -ge $limit ]] && break
    done
    if [[ $num -ge $limit ]]; then 
        { printf %s "$buffer$line"; cat } | less
    else
        printf %s "$buffer$line"
    fi
}

La chiave è che il guscio deve sapere se il ci sono più righe nel file rispetto allo schermo prima che (potenzialmente) lancia less (la tecnica multi-io inizialmente usato può essere eseguito solo cose nei precedenti). Se il read in guscio non è abbastanza robusto per voi, è possibile sostituirlo con rielaborazione del codice un po ':

function cat_up_to_N_lines_and_exit_success_if_more() {
    # replace this with some other implmentation
    # if read -r is not robust enough
    local line buffer='' num=0 limit="$1"
    while IFS='' read -r line; do
        buffer="$buffer$line"$'\n'
        line=''
        num=$(( num+1 ))
        [[ $num -ge $limit ]] && break
    done
    printf %s "$buffer$line"
    [[ $num -ge $limit ]]
}
function catless() {
    local limit=$LINES buffer=''
    # capture first $limit lines
    # the \0 business is to guard the trailing newline
    buffer=${"$(
    cat_up_to_N_lines_and_exit_success_if_more $limit
    ec=$?
    printf '\0'
    exit $ec)"%$'\0'}
    use_pager=$?
    if [[ $use_pager -eq 0 ]]; then
        { printf '%s' "$buffer"; cat } | less
    else
        printf '%s' "$buffer"
    fi
}

Altri suggerimenti

La bandiera -X potrebbe dare una mano (da meno (1)):

  -X or --no-init
         Disables sending the termcap initialization and deinitialization
         strings to the terminal.   This  is  sometimes desirable if the
         deinitialization string does something unnecessary, like
         clearing the screen.

Quindi, il seguente dovrebbe fare quello che vuoi:

export LESS="-E -X"

In alternativa, dal momento che vi piace --quit-se-un-schermo, si potrebbe invece:

export LESS="-F -X"

less ha un'opzione --clear-screen (disponibile anche come -c. Si potrebbe voler controllare la variabile d'ambiente LESS $ per assicurarsi che lo fa non includono questa opzione. Il mio non e si comporta esattamente come si vogliono (non come si sta cercando di superare).

È possibile disattivare le opzioni impostate nella variabile $ LESS su un ad hoc utilizzando +. Ad esempio:

less -+c shortfile

Si dovrebbe anche fare in modo che $TERM sia impostata correttamente.

Se tutto il resto fallisce, guardare il $LESSOPEN pre-processore e $LESSCLOSE caratteristiche post-processore nella sezione "INPUT PREPROCESSOR" di man less per vedere se questo ti porta ad un altro approccio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top