bashless-unix

Why is less acting like cat?


I've been searching and testing for hours. I finally found that less paginates if it is called from the main body of the bash script. But it acts like cat if called from a function or inside {}. I've tried pipes and also using a temporary file.

I tried a test script without tee to a logfile and it worked OK. With the {}, less did not paginate. Maybe I need a better way to save the script output. I'm using "less -R" because it is going to use color diff.

#!/bin/bash
#

tryit()
{
    longfile=$(mktemp)
    /bin/ls -R /etc 2>/dev/null > $longfile

    less -R $longfile
}

{
    tryit
} 2>&1 | tee SOME_LOGFILE

Solution

  • less only mediates between its stdin and a terminal when its output is connected to a terminal; when you connect its output to the input of another command (like tee), there's no terminal for it to communicate with.


    In the general case, tee belongs before less in your pipeline, not after it: less needs to be the last thing before the terminal to operate as intended, because its purpose is to feed content to a terminal in a user-friendly way; it doesn't make sense to page to a file, because files don't have a screen that someone wants to scroll around it.


    If your specific purpose is to log exactly what was and wasn't read by the user at the terminal (potentially as well as timings, input, etc depending on optional arguments added), use script instead:

    #!/bin/bash
    #
    
    tryit()
    {
        longfile=$(mktemp)
        /bin/ls -R /etc 2>/dev/null >"$longfile"
    
        less -R "$longfile"
    }
    
    export -f tryit
    script SOME_LOGFILE bash -c tryit