Skip to content
Sign upLog in
← Back to Community

Building a CLI

Profile icon


Have you ever wanted to make a CLI (Command-line Interface)? Well I have, and if you're reading this, you probably want to too. So, let's begin!
First, boot up a bash repl. Open up the shell, and type in this:

mkdir bin && cd bin && printf "" > ./foo && cd ..

and with that, you should have a new directory, "bin", and one file in bin named foo. If you don't want a CLI named foo, then rename it something else. Just DON'T give it a file extension. (.sh, .cpp, etc.)
Open bin/foo and put in this one line:


This line sets this file's language to bash, and so if you run ./bin/foo, it will be the same as bash ./bin/foo.
In our foo file, let's add this line of code:

printf "Hello world!\n"

Now, if you run foo in the shell:

bash: foo: command not found

Oh, wait, I forgot. First you have to type this in the shell:

export PATH="$(pwd)/bin:$PATH" && chmod -R +x ./

and then:

~/demo$ foo Hello world!

So, now if you run foo, it will run the foo file!

Expanding your CLI

Ok, now, what are some things most CLIs have?

User input

User input is very important, it lets users have more control, and it is very useful for asking questions. So, let's change our code a little bit. Add this to the end of your foo code:

read -p "Is foo part of the word foobar? [y/n]" answer answer="${answer,,}" if [[ "$answer" == "y" ]]; then printf "Correct!\n" else printf "Incorrect, the correct answer is y.\n" fi

so now, your foo code should look like this:

#!/bin/bash printf "Hello world!\n" read -p "Is foo part of the word foobar? [y/n]" answer answer="${answer,,}" if [[ "$answer" == "y" ]]; then printf "Correct!\n" else printf "Incorrect, the correct answer is y.\n" fi

So, our foo CLI will be a short quiz. If the word foobar contains the word foo, then enter y. If the word foobar does not contain the word foo, enter n.
The read command lets us read user input. The -p (prompt) lets us add a prompt for the user, the "" text is the text for the prompt, and the answer part creates a variable accessible by using "$answer".
answer="${answer,,}" converts the answer to lowercase.
The if/else statement runs the top code if the user answered yes, or the bottom code if they answered anything else, it runs the bottom code.


Colors are very important, otherwise everything is just plain text! So, to add colors, we can use ANSI Escape Codes.
To color text, first add this: \033[mHello world!
Then, add numbers: \033[96mHello world!
Here is a color chart:
color chart

(96 = bright cyan)
You can also add bold text (\033[1;96m) (1 = bold), underlined text (\033[4;96m) (4 = underlined)
30-37 and 90-97 set foreground (text) color, 40-47 and 100-107 set background color.
Let's change the code a little bit more, replace your code with this changed code:

#!/bin/bash printf "\033[1;96mHello world!\n\033[0m" read -p "Is foo part of the word foobar? [y/n]" answer answer="${answer,,}" if [[ "$answer" == "y" ]]; then printf "\033[92mCorrect!\n" else printf "\033[91mIncorrect, the correct answer is y.\n" fi

Options / arguments

To access arguments, use the [email protected] variable. If someone types foo bar, then [email protected] will be bar. If someone types foo --bar, then [email protected] will be --bar. If someone types foo bar --foobar, [email protected] will be bar --foobar, $1 will be bar, and $2 will be --foobar.


If you get an error, look here for answers.

  • bash: foo: command not found
    If you get a command not found error, run export PATH="$(pwd)/bin:$PATH" && chmod -R +x ./ again.
  • Bad substitution
    Make sure the first line is #!/bin/bash.
  • Color code displays code, not color
    Look for typos, sometimes I type \003 instead of \033, which gives me an error, and make sure you are using printf, not echo.
    If you get any other errors, put them in the comments, and I will add the solution to this section.

Thanks for reading!

Profile icon
Profile icon
Profile icon
Profile icon
Profile icon

Well done! One thing I would add more things to the CLI, like asking for the users name and more. That might be getting into advanced bash, but it would be a really good resource when making a CLI.

Profile icon

How do you make password entrance without using echo?