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.

Table of contents

    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!

    Mateusz Osiński
    Mateusz Osiński Elixir Developer

    Read more
    on #curiosum blog