How to create and use custom shell commands?

Article autor
September 9, 2025
How to create and use custom shell commands?
Elixir Newsletter
Join Elixir newsletter

Subscribe to receive Elixir news to your inbox every two weeks.

Oops! Something went wrong while submitting the form.
Elixir Newsletter
Expand your skills

Download free e-books, watch expert tech talks, and explore open-source projects. Everything you need to grow as a developer - completely free.

Table of contents

Each of us had a situation, where we had to invoke a few, same commands each time. Making it once is not that problematic, but when we are supposed to repeat given operations, it may be better just to create one function that will handle it all.

Create own functions

To create our own functions, firstly we need to open a new terminal. By default, we ought to be in the root directory (~), but to be sure you can execute the following command:

cd ~

and hit enter.

Right now, we can create a new file, in which we will store our function with commands. To do it, execute this:

touch .custom_bash_commands.sh

The naming convention is up to you, in this case, the file will be named .custom_bash_commands.sh , where '.' at the beginning means it is a hidden file. To see all of the hidden and visible files, you can just do ls -a.

Once we have created the file, we can open it. To do so, you can use VIM or your favorite text editor. I will be using Visual Studio Code. For that, I will execute the following command in my current directory:

open -a 'Visual Studio Code' .custom_bash_commands.sh

Now, we can create our function by following:

#!/bin/bash

function mix_all(){
  echo "mix format"
  mix format
  echo "mix static.credo"
  mix static.credo
  echo "mix dialyzer"
  mix dialyzer
  echo "mix test"
  mix test
}

The first line is just a convention, which is used while creating Scripts. Next, we have function declaration, which is called mix_all .

We use echo command to print out the following state. Of course, this is just a sample function, you can use whatever you want to up here.

Remember about saving the file now!

Source it and use it!

The next step is to source it into Bash/ZSH main file here. Why? Right now, the function is already created and can be used everywhere on our computer (but, in the following example, we have to have installed all needed dependencies in our project).

If you source it by executing:

source ~/.custom_bash_commands.sh

and invoke the function name:

mix_all

You will be prompted with the output of commands inside our mix_all , each by each.

But, it will be only available for the given directory and current session. If you will try to open a new terminal tab in the same directory and execute the function again, it will fail.

To omit that, let's come back to the root directory and open the .zshrc or .bashrc file (the file is dependent on your current OS version). In my case, I am going to open the .zshrc file:

open -a 'Visual Studio Code' .zshrc

And to make things work, we just need to source the previously created file here:

source ~/.custom_bash_commands.sh

And that's that. Right now we instruct our terminal to load our file on each terminal session. You can obtain your own command from any place you want to, without sourcing it.

Another example

The following function is just a really basic example. Let's create one more function, that will hold other operations. In the root directory, I am going to open the file, which I created at the very beginning. Inside of file, I am going to create another function:

#!/bin/bash

function mix_all(){
  # Previously created function
}

function create_user(){
  echo "User creation function"
  sudo dscl . -create /Users/$1
  sudo dscl . -create /Users/$1 UserShell /bin/bash
  sudo dscl . -create /Users/$1 RealName $2
  sudo dscl . -create /Users/$1 UniqueID $3
  sudo dscl . -create /Users/$1 PrimaryGroupID 1000
  sudo dscl . -create /Users/username NFSHomeDirectory /Local/Users/$1
  sudo dscl . -passwd /Users/username $4
  if dscl . list /Users | grep $1 ;
  then
    echo "User has been created!"
  else
    echo "Failed."
  fi
}

This function will allow us to omit 7 commands of user creation, for just one. The numbers prepend with a dollar sign are variables (eg. $1), and each of them stores a given value. The only things we need to remember are the name of our function and the order of passed arguments.

We do not have to source it now, because we have already done it previously. Just remember about saving the file! In our example, the order is:

function_name user_name users_real_name unique_user_id user_password

Just be sure, that unique_user_id is unique.

To execute the following function and create a user, let's move back to the terminal and just execute:

create_user curiosum Curiosum 1001 JustStayCuorius!

And that's that! For now, the user creation operation is automated. It is just a basic function for that usage, we could handle more sophisticated things here, such as error handler, or password validator.

Summary

In a very undemanding and fast way, we were able to omit invoking four and seven commands for just one function. The following code is just an example, and you can use your own created functions in many more ways! Bash is userfriendly, and helps us a lot in automating our workflow. It's good to get to know it well!

Related posts

Dive deeper into this topic with these related posts

No items found.

You might also like

Discover more content from this category

How to revert commit in Git

Did you ever create a commit that you wish never happened? Let's be honest - we all did. There is an easy way to revert it in Git.

How to change column to nullable with modify in Ecto migration

Sooner or later you'll have to change the null constraint in one of your DB relations. How to do it easily in Ecto?

How to set default value in JavaScript’s Destructuring

Did you know that it's possible to set default value in Javascript object destructuring?