Bash manual page selection menu

General Tech Learning Aids/Tools 2 years ago

0 2 0 0 0 tuteeHUB earn credit +10 pts

5 Star Rating 1 Rating

Posted on 16 Aug 2022, this text provides information on Learning Aids/Tools related to General Tech. Please note that while accuracy is prioritized, the data presented might not be entirely correct or up-to-date. This information is offered for general knowledge and informational purposes only, and should not be considered as a substitute for professional advice.

Take Quiz To Earn Credits!

Turn Your Knowledge into Earnings.

tuteehub_quiz

Answers (2)

Post Answer
profilepic.png
manpreet Tuteehub forum best answer Best Answer 2 years ago

 

I wrote the following script in the hopes of streamlining the finding and reading of multiple manual pages. Since I am always looking up different utilities' manual pages I thought this would a good learning aid.

#!/bin/bash

while true
do
    echo
    echo "1) /bin"
    echo "2) /sbin"
    echo "3) /usr/bin/"
    echo "4) /usr/sbin"
    echo "5) /usr/local/bin"
    echo "6) /usr/local/lib"
    echo "7) /usr/local/share"
    echo "8) /usr/local/include"
    echo "9) exit"
    echo
    read -p 'Select a directory ' d
    if [[ $d = 1 ]]; then
        dir=/bin
    elif [[ $d = 2 ]]; then
        dir=/sbin
    elif [[ $d = 3 ]]; then
        dir=/usr/bin
    elif [[ $d = 4 ]]; then
        dir=/usr/sbin
    elif [[ $d = 5 ]]; then
        dir=/usr/local/bin
    elif [[ $d = 6 ]]; then
        dir=/usr/local/lib
    elif [[ $d = 7 ]]; then
        dir=/usr/local/share
    elif [[ $d = 8 ]]; then
        dir=/usr/local/include
    elif [[ $d = 9 ]]; then
        exit
    else
        echo 'No such directory'
        exit 1
    fi
    echo
    while true
    do
        menu=( $(ls -1 ${dir}) )
        i=0
        for m in ${menu[@]}
        do 
            echo "$(( i++ ))) $(basename $m)"
        done | xargs -L3 | column -t
        echo
        echo 'Select from the list above'
        echo 'Type b to go back to main menu'
        read -p 'Type q to quit at anytime ' n
        echo
        if [[ $n = 'b' || $n = 'B' ]]; then 
            break 1
        elif [[ $n = 'q' || $n = 'Q' ]]; then
            exit
        else 
            for item in ${menu[$n]}
            do 
                if [[ $item =~ '.txt' ]]; then
                    item=
                                                
                                                
0 views
0 shares
profilepic.png
manpreet 2 years ago

Use a table driven menu

The menu to select from /bin/sbin and other is very repetitive. A table-based approach would be more compact, easier to write and maintain. Try to use an array, as you did in other places of the script.

First, put the directories in an array, for example:

dirs=('' /bin /sbin /usr/bin)  # fill the rest

Note that I added a dummy empty first element. This is to make the 1-based indexes of your menu work with the 0-based array indexes.

Build the menu from this array using a counting loop from 1, the first non-empty element:

for ((index = 1; index < ${#dirs[@]}; index++)); do
    echo "$index) ${dirs[$index]}"
done

To validate the user input, simply check if ${dirs[$index]} is empty. If yes, the input is invalid.

Security

Maybe it is normal to have plain text files in this directory or maybe this is something I did unintentionally when experimenting writing this script. (An earlier version of this script wrote all the man pages to plain text files.)

No, it is not normal to have .txt files in any of those directories. So I guess your earlier script put them there. But a normal user should not have write access to these directories. Which seems to suggest that you're playing with a privileged account, possibly root. That's a bad idea, avoid using root casually.

Simplify

You can simplify [[ $n = 'b' || $n = 'B' ]] using pattern matching: [[ $n == [bB] ]].

Strangeness

You don't need the -1 here.

menu=( $(ls -1 ${dir}) )

When inside $(...)ls does not columnize its output.


In this code, I don't see why you need basename:

echo "$(( i++ ))) $(basename $m)"

It seems the value of $m will always be a simple filename without a path part.


0 views   0 shares

No matter what stage you're at in your education or career, TuteeHub will help you reach the next level that you're aiming for. Simply,Choose a subject/topic and get started in self-paced practice sessions to improve your knowledge and scores.