Search code examples
bashshellless-unix

Is there a way to reproduce 'less' screen behavior in bash?


I try to make a simple bash script that runs multiple tools, like dehader, cppcheck and a bunch of custom tools, and for readability, it cleans the terminal between each tool, and wait for the user to press the enter key before running the next tool.

clear
rm *.o
echo "removed object files"
rm __pycache__
echo "removed python cache files"
echo "everything cleaned, press enter to continue"
read a

clear
deheader
echo "deheader done, press enter to continue"
read a

clear
cppcheck
echo "cpp check done, press enter to exit"
read a

clear

Simple reproduction of what my script does

But I don't like this solution, because I want this script to execute in another screen (I don't know how to call it exactly), just like less does. This way, I could keep my terminal just like it was before the script call. Even if they aren't close to the less behavior, any suggestions that could help me are welcome.

I searched online what I could do to reproduce this behavior, but didn't find anything. I'm starting to doubt that's even possible.

Note: I don't want the 'scrolling' less behavior. I mean, there's no problem if I have to use it, but I don't particulary want it.


Solution

  • Thanks to the comments, I figured it out.

    From what I can understand, there are two ways to do it with the "cursor addressing mode":

    • By using tput smcup/rmcup
    • By entering/exiting the "cursor addressing mode" manually, when priting the escapes sequences related

    This mode in terminal-implemented and is not supported by all terminals - and not always in the same way, for example multiple terminals don't reset the cursor position after entering this mode, so don't forget to clear your terminal - but is fortunately supported by a large majority of modern terminal emulators.

    smcup/rmcup

    Simply use the tput smcup command, and then, restore it using tput rmcup.

    Example:

    # save, clear screen
    tput smcup
    clear
    
    # example "application" follows...
    read -n1 -p "Press any key to continue..."
    # example "application" ends here
    
    # restore
    tput rmcup
    

    source

    Escape sequence

    You can enter this mode using printf \\33\[\?1047h, then leave it using printf \\33\[\?1047l.

    Example:

    # save, clear screen
    printf \\33\[\?1047h
    clear
    
    # example "application" follows...
    read -n1 -p "Press any key to continue..."
    # example "application" ends here
    
    # restore
    printf \\33\[\?1047l
    

    more informations

    Try to avoid using both methods in the same code, or using one method to enter this mode and another to exit it, as it could lead to unexpected behavior.

    Personnaly, I prefer the tcup method as it's more readable and supported by all Unix systems.