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! Commented Nov 29, 2019 at 15:05

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.