💪 You Can: Write a shell script!
Today I finally simplified some tasks I keep doing over and over again. These tasks are exactly what shell scripts are useful for!
Re-published on Medium.
Today I finally simplified some tasks I keep doing over and over again. These tasks are exactly what shell scripts are useful for!
I’ll list 5 steps to writing your own basic shell script! You can easily extend it after.
If you’re new to development or have not written a shell script before, this is for you!
We’re going to write a script called marvin
🤖 that will pull from two different git repositories with one command and start a database with another.
1. Create your file!
The file you create needs to be accessible from the terminal. For this, the file should be in a directory that is in your PATH variable.
Run echo $PATH
from your terminal to see which directories are present.
You may see something like this:
$ echo $PATH
/Users/Manil/.rvm/gems/ruby-2.3.0/bin:/Users/Manil/.rvm/gems/ruby-2.3.0@global/bin:/Users/Manil/.rvm/rubies/ruby-2.3.0/bin:/Users/Manil/.nvm/versions/node/v5.10.1/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/Manil/bin:/Users/Manil/.rvm/bin:/Users/Manil/.rvm/bin
One of the directories in there (directories are separated by colons) is /Users/Manil/bin
This is where I chose to create my script file.
Create a new file in your own directory of choice called marvin
. You can run touch marvin
from the terminal in the directory to make a new file.
Now this file needs to be executable; that is, it should be allowed to run like you would a program. You can do this by telling your terminal to:
$ chmod +x marvin
Awesome 🎉
2. Begin your script!
Now open your marvin
file in your favourite text editor!
All shell scripts begin with this #!
, a shabang. This tells the computer how to run the script.
At line 1 of our script, we’ll write:
1 | #!/bin/sh
This part will help structure your script because as you write it, you will need to think about what your script will do. Also nothing is complete without help text!
My help text began as:
1 | #!/bin/sh
2 |
3 | function help () {
4 | echo " here's the help text!"
5 | echo ""
6 | echo " 🤖 marvin - your helpful robot friend."
7 | echo ""
8 | echo " update - pull new code from "
9 | echo " ignitedb - starts the db "
10 | }
You’re ready to write the logic!
3. The first if
statement.
This is mainly to make sure some parameter has been passed in along with the terminal command. Otherwise it will call the help function, which you defined earlier.
8 | echo " update - pull new code from "
9 | echo " ignitedb - starts the db "
10 | }
11 |
12 | if [ $1 ]
13 | then
14 | # marvin does its thing
15 | else
16 | help
17 | fi
Run marvin
from the terminal and this will appear:
$ marvin
$ here's the help text!
$
$ 🤖 marvin - your helpful robot friend.
$
$ update - pull new code from
$ ignitedb - starts the db
Because there was no parameter passed in, line 12 executes to false and the help function is called. This function prints what you see into the terminal!
Well done! 👏
4. The case
statement.
The case statement lets you control what your script executes when you give it different parameters from the command line! 🙌
$ marvin dothething
We’ll write a simple case statement, which begins on line 14.
8 | echo " update - pull new code from "
9 | echo " ignitedb - starts the db "
10 | }
11 |
12 | if [ $1 ]
13 | then
14 | case "$1" in
15 | update)
16 | echo " ⚡️ jazzing up your web client."
17 | cd /Users/Manil/development/client && git pull --rebase
18 | echo " ⚡️ jazzing up your api ."
19 | cd /Users/Manil/development/api && git pull --rebase
20 | ;;
21 | ignitedb)
22 | echo " 🔥 db igniting"
23 | mysql.server start
24 | ;;
25 | *)
26 | echo " 🤖: what should I do?"
27 | ;;
28 | esac
29 | else
30 | help
31 | fi
In line 14, we’re telling the case
statement to use the first parameter ($1
) given to marvin
.
Line 15 begins the statement where we tell our script what to do when it gets update as the parameter.
Lines 16–19 directs the shell to two different directories. From each of these directories it executes a git pull
. These lines would be executed if we told the terminal to:$ marvin update
Similarly, lines 22 and 23 would be executed if we told the terminal to:$ marvin ignitedb
The ;;
tells the case
statement where each part ends.
The *)
on line 25 is a catch-all in case we accidentally pass in an undefined parameter. It tells the script to just print line 26 onto the terminal when that happens.
$ marvin sharejokes
$ 🤖: what should I do?
5. Next steps: Extending your shell script!
As you extend your script, you may find that extracting your code into reusable functions will help simplify a script that starts becoming very lengthy and repetitive. All code grows, just remember to DRY (Don’t Repeat Yourself) it up!
Your shell script can do whatever you want it to!
6. Bonus step: Share your script! If your script helps a project, include your script in its repository.
I wrote a shell script to save time refreshing my test environment.
In my team, I help automate our app’s end-to-end tests.
The tests I write need to be current with the app’s HTML structure. If they can’t find the elements they’re looking for, the tests will fail!
Ideally, as the functionality being tested changes, we fix the tests. This way we save some time between the end of a sprint and deploying to production. It’s difficult to do that without the latest commits made by our team!
So I need to be working with the latest code. To get that, I pull new commits from our remote repositories. I rebuild the web-client. I reset the testing database to start with a clean slate. And so on. It’s lengthy, repetitive and tedious.
The last thing I did was to move the script to the test repository. I created the script to help work on the tests. So it seemed sensible to include it for anyone who might find use for it. To let marvin
be run in the terminal from its new location, I symlinked the script file to its original location which is recognized by the $PATH variable.
Tell your terminal to:
$ ln -s /Users/Manil/development/test-repository/bin/marvin /Users/Manil/bin/marvin
$
The command ln
(link) takes the flag -s
which symbolically links the current location of the script file (first path) to where I want it linked (second path, where is was previously). See that there is a space between the two paths!
These need to be done frequently to keep up with with changes. With a shell script, repetitive tasks become simpler to complete. I can go make a tea 🍵 while all the steps run in one go instead of my having to execute them one by one!
Now that you know writing a shell script is very similar to other programs that you write, it’ll be easier to add tools that you think can simplify the tasks you work on everyday!