1

I want to make a CLI using bash for fun. I want to have a read prompt like

CLI/[path]/:>

easy

read -p "CLI$PWD/:>"

but if I want to do a command like cd then I will have to make a whole interface to change the directory. I know how to do all of the other basic commands, but my main goal is to be able to switch my directory in one command.

EG:

CLI/[path]/:>cd [another path]
CLI/[another path]/:>

My script so far:

#!/bin/bash

echo "Welcome to Easy Command-Line Interface! Type 'help' for help and 
commands."

while true; do

    read -p "ECLI$PWD/:>"
    if [ $REPLY = "help" ]; then
        echo "ECLI HELP:"
        echo "help: Help Menu"
        echo "cd: <dir> : Changes Directory"
        echo "say: <text> : Prints <text>"
        echo "exit: Exits ECLI"
        echo "clear: Clears screen"
        echo "
        "
    fi

    if [ $REPLY = "exit" ]; then
        echo "Exiting ECLI.."
        sleep 1.5
        clear
        break
    fi

    if [ $REPLY = "clear" ]; then
        clear
    fi


done

1 Answer 1

0

First of all, you’ve got to start using quotes.  Surely you’ve noticed that

if [ $REPLY = "command" ]
fails (and gives a [: too many arguments error message) if you type a command line with more than one word.  You need to change that to

if [ "$REPLY" = "command" ]

Approach 1: Read the line and extract the first word

I presume you understand that your current script gets an entire input line into $REPLY.  But, if the user types cd /usr/local, it does you no good to compare cd /usr/local to cd; you need to extract the first word of the input line.  You can do this with word1="${REPLY%% *}".  This is an instance of parameter expansion, which you can read about in bash(1) or the POSIX specification.  So you could modify your script as follows:

     ︙
    if [ "$REPLY" = "clear" ]; then
        clear
    fi
 
    word1="${REPLY%% *}"
    if [ "$word1" = cd ]
    then
        $REPLY
    fi

Approach 2: Read the first word separately

It’s rare that you want to read an entire line; more often (as in this example) you want the shell to break the line apart into words.  You do this by giving the read command a list of variables to read into:

     ︙
    read -p "ECLI$PWD/:>" cmd args
     ︙

    if [ "$cmd" = "clear" ]; then
        clear
    fi

    if [ "$cmd" = cd ]
    then
        cd "$args"
    fi

Approach 3: Read each word separately

The above approaches are fine for proof-of-concept toys.  In a real application, you would want the shell to break the input line into however many words there are.  You do that by reading into an array, using the -a option:

     ︙
    read -p "ECLI$PWD/:>" -a arr
     ︙
 
    if [ "${arr[0]}" = "clear" ]; then
        clear
    fi
 
    if [ "${arr[0]}" = cd ]
    then
        cd "${arr[1]}"
    fi

1
  • thank you! this is exactly what I needed! Approach 1 worked for me, I edited the code a bit so it couldn't go outside my projects main folder! I have asked this question many times, and it was misunderstood, now I finally have what I need! Nov 29, 2019 at 15:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .