As the title implies this article will be covering Bash Shell Scripting at a beginner level. I’m not going to review the history of Bash but there are many resources to fill you in or you can visit the GNU project at https://www.gnu.org/software/bash/. We will start out with understanding some very basic concepts and then start to put things together.
Creating a script file
The first thing to do is create a script file. First make sure the home directory is the current directory.
cd ~
In the home directory, create the example file. This can be named anything but learnToScript.sh will be used in this article.
touch learnToScript.sh
From this point there will be a file called learnToScript.sh in your home directory. Verify it exists and also notice the privileges for that file are -rw-rw-r– by typing the following.
ls -l
[zexcon@trinity ~]$ ls -l total 7 drwxr-xr-x. 1 zexcon zexcon 90 Aug 30 13:08 Desktop drwxr-xr-x. 1 zexcon zexcon 80 Sep 16 08:53 Documents drwxr-xr-x. 1 zexcon zexcon 1222 Sep 16 08:53 Downloads -rw-rw-r--. 1 zexcon zexcon 70 Sep 17 10:10 learnToScript.sh drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Music drwxr-xr-x. 1 zexcon zexcon 318 Sep 15 13:53 Pictures drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Public drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Videos [zexcon@trinity ~]$
There is one more thing that needs to be done to get started. Let’s try and execute the script with nothing written in it. Type the following:
./learnToScript.sh
[zexcon ~]$ ./learnToScript.sh bash: ./learnToScript.sh: Permission denied
You get permission denied because there are no execute permissions on the file. You need to change the permissions of the file to be able to execute the script. If you are not familiar with permissions I would recommend reading the Fedora Magazine articles written by Paul W. Frields:
Command line quick tips: Permissions
Command line quick tips: More about permissions
At this point you’ve brushed up on permissions, so back to the terminal and let’s change the learnToScript.sh file so it will execute. Type in the following to allow execution of the file.
chmod 755 learnToScript.sh
[zexcon@trinity ~]$ ls -l total 7 drwxr-xr-x. 1 zexcon zexcon 90 Aug 30 13:08 Desktop drwxr-xr-x. 1 zexcon zexcon 80 Sep 16 08:53 Documents drwxr-xr-x. 1 zexcon zexcon 1222 Sep 16 08:53 Downloads -rwxr-xr-x. 1 zexcon zexcon 70 Sep 17 10:10 learnToScript.sh drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Music drwxr-xr-x. 1 zexcon zexcon 318 Sep 15 13:53 Pictures drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Public drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Videos [zexcon@trinity ~]$
Okay now you’re ready, you have read, write and execute permissions (-rwxr-x r-x) to the learnToScript.sh command.
Editing a script file
Take a moment and make certain you are familiar with vim or any text editor. Throughout this article I will be utilizing vim. At the command prompt type the following:
vim learnToScript.sh
This will bring you to an empty text file with a bunch of tildes in it. Type i on your keyboard and this will move you into — INSERT — mode. You can see it’s in this mode by looking at the bottom left of the terminal window. (Note that an alternative editor is the nano editor.)
From here you need to make sure that the file is recognized by the correct interpreter. So enter the shebang ( #! ) and the directory to your bash, /bin/bash:
#!/bin/bash
One last thing that you will use throughout the article is saving the document. Hit Esc to leave input mode, then Shift + Colon. At the colon you will enter wq. This will write(w) the file and quit(q) vim once you hit enter.
A few things to remember while using vim, anytime you want to write into a document you need to enter i and you will see –INSERT– at the bottom. Anytime you want to save, you will need to hit Esc to leave input mode, and then Shift+: to enter w to write the file or Esc then Shift+: to enter q to quit and not save. Or add both wq together and it will write and close. Esc by itself will exit INSERT mode. You can find much more about vim at it’s website or this get started site.
Lets start scripting…
echo
The echo command is used to return something to the terminal. You will notice that you can use single quotes, double quotes or no quotes. So let’s take a look at it with a traditional Hello World!
#!/bin/bash echo Hello World! echo 'Hello World!' echo "Hello World!"
[zexcon ~]$ ./learnToScript.sh Hello World! Hello World! Hello World! [zexcon ~]$
Notice that you get the same result with all three options. This is not always the case but in this basic script it is. In some circumstances the type of quotes will make a difference. By the way, congratulations you have written your first Bash script. Let’s look at a few things that you will want to know as you continue to create more scripts and let your mind run wild.
Command Substitution $( ) or ` `
Command substitution allows you to get the results of a command you might execute at the command line and write that result to a variable. For example if you type ls at the command prompt you will get a list of the current working directory. So let’s put this into practice. You have two options for command substitution. Note that the first option uses a back tick found above the Tab key on the left side of the keyboard. It is paired with the tilde ~ key. The second option uses a shell variable.
#!/bin/bash command1=`ls` echo $command1 command2=$(ls) echo $command2
[zexcon ~]$ ./learnToScript.sh Desktop Documents Downloads learnToScript.sh Music Pictures Public snap Videos Desktop Documents Downloads learnToScript.sh Music Pictures Public snap Videos [zexcon ~]$
Notice no space between the variable, equal sign, and the start of the command. You get the exact same result with both options. Note that variables need to be led by a dollar sign. If you forget and you echo out the command variable without the dollar sign you will just see the name of the command as shown in the next example.
#!/bin/bash command1=`ls` echo command1 command2=$(ls) echo command2
[zexcon ~]$ ./learnToScript.sh command1 command2 [zexcon ~]$
Double Parentheses (())
So what are double parentheses for? Double parentheses are simple, they are for mathematical equations.
#!/bin/bash echo $((5+3)) echo $((5-3)) echo $((5*3)) echo $((5/3))
[zexcon ~]$ ./learnToScript.sh 8 2 15 1 [zexcon ~]$
Conclusion
At this point we have created our first script. We have an idea how to take several commands, place them in a script and run it to get the results. We will continue this discussion in the next article and look at redirection of input and output, the pipe command, using double brackets or maybe just adding some comments.
Athan
The chmod command is inconsistent with what the targeted outcome is.
Stephen Snow
Hello, good catch,
I changed it to “chmod 755 to be consistent with the results displayed . Oops, it was correct originally so I retracted my change.Donald Sebastian Leung
Wouldn’t it be better to change both (1) the command to
and (2) the output of
to match the command?
permissions is weird (and insecure) because anyone can edit your script, even if you are the only one that can execute it.
Or just
and you don’t have to worry about accidentally making your script world-writable.
Richard England
That was missed in editing. It has been corrected.
Bthan
It’s still wrong. The listing says “-rwxrw-rw-” but below the listing you say “execute permissions (-rwxr-xr-x)”.
Chmod 766 is wrong. 6 is read and WRITE, so a security issue that others can alter your script on the fly. Use 755 instead.
Why don’t you use “chmod +x” to give execute permissions?
Oh, and BTW. the link to Paul W. Fields is broken too.
Richard England
Corrections were made for the permissions. But the links to the other articles appear to be correct. What are you seeing when attempting to view them?
Bthan
Actually, the link is not broken, but it’s an empty page.
The link to Paul’s profile:
“… recommend reading the Fedora Magazine articles written by Paul W. Frields.”
The page says:
This page is primarily used internally
Richard England
The link to Paul W. Frields should not have been a link. The two images (that are links to the two articles) are the important part. The OpenID link has been removed.
Scott Auge
LOL I read it because there is “always a sentence of interest reading” and that’s the truth, because $(()) was new to me and I had read two bash manuals!
Daniel
Good.
Breno
I would recommend
instead of
at a beginner level. Also,
sounds more intuitive for a beginner to me.
Thuur
You can also check this permission site :
http://permissions-calculator.org/
Anil F Duggirala
Thanks so much for this. Always been curious about these scripts. Thanks for allowing me to get into it so smoothly.
I already know vim, I hope your other readers don’t get lost or discouraged by getting stuck with vim. Also, keep in mind that there are various different keyboard layouts, not just US English.
thanks so much,
zexcon
Thank you I’ve added the specification into the next article for clarification on the keyboard.
person
Why do i have to be at ~
Joao Rodrigues
You don’t have to be at ~. You can place your script anywhere you have write permission.
You could, for example, place it in ~/.local/bin or ~/bin. These directories are ususally in your $PATH, so you could call your script from any directory by just typing “learnToScript.sh” instead of “~/learnToScript.sh”
zexcon
You don’t have to be in your home directory. This is only for simplicity of the article. You can place your script any place you just need to specify the path or be in the location to run the script.
Smackeyacky
The file listing of the directory containing your script shows the right permissions for chmod 766, but the text underneath says you wanted rwxr-xr-x which is 755. Change the command to 755 and fix the listing of files and it will be consistent.
Darvond
While I’d never suggest vim for a beginner, I do understand it is the defacto. (For some reason; though it and emacs have been outmoded for years in terms of sheer sanity by others.)
But! Fedora’s default editor is nano; should that not be the editor invoked accordingly?
Instead of the one that requires complex bespoke keystrokes just to enter insertion mode?
Richard England
For some (perhaps many) vi/vim is what they know and it was the standard editor for some time. A note has been added pointing out that nano is an alternative. The point of the article was not the editor to use rather the script that was being created.
But thank you for your input.
Brian
I never had any trouble using vim or vi when I was teaching myself to program from the command line. What is the point in trying to discourage beginners from learning something that is NOT THAT DIFFICULT in the first place? Entering insertion mode in vi or vim requires — i . Leaving insertion mode requires the– Esc — the escape key. This is difficult ? Saving a file requires– :wq and the name of the file if it’s a new file — :wq ./Boogers
Quiting without saving requires– :q! How hard is that? Personally, I don’t like nano at all.
Aside from that, I’ve had Fedora on my box for 20 years, and I never had nano installed at all until last year.
Darvond
Beg pardon from someone born after the German Reunification and ergo; the Emacs/Vim Holy Wars.
The way my opinion flows is this: When people open an editor, they want to edit. Drop in, start typing.
But it may also be worth noticing that no graphical editor really goes out of their way to emulate vi because you just focus the window and type.
Even ancient tools from the other side of the force like QBASIC’s Editor didn’t require anything weird to get going.
Richard England
…and the wars continue. 🙂
Inci
Great intro! Looking forward for part 2.
edier88
Great!
This is really important for sysadmins and developers.
Looking forward for the next parts!
Stathis
You might want to consider changing the shebang line of the script to
This seems to be preferred nowadays.
As it does not assume “bash” to be present in a specific directory it helps promote portability.
Joao Rodrigues
Well, that just assumes “env” is present in /usr/bin
You have to put an absolute path in the hashbang. You have to start assuming something at some point. If for some reason bash is not in /bin, a more sensible approach would be just to symlink bash in /bin.
Bryan
Very nice article sir
Putin
Unrelated to the above topic at hand, I wish to say that I now love Fedora. Been using Ubuntu and its derivatives for the past 20 years until a couple of weeks ago where I just happened to stumble upon the Distrowatch website. Yes, I never knew it existed. Wanted a change of scene and somehow Fedora looked very enticing. Got it installed on main machine without a second thought. Loving it. The community is fantastic. Keep it up folks.
Pedgerow
Thanks for this! Please explain how to take input in a future article. I have never been sure about how to do this, but I assume it’s very basic. By this I mean, how can I pass an argument to a Bash script? Like if I wanted to write a script that did the same as “echo”, and it only contained one command and that was “echo $input”, what else would I need to put in the script to make it work?
Also, does it have to start with #!/bin/bash, or can it start with something else? What if I put the script file (echov2.sh or whatever) in a different path? It would be very cool if you could answer these questions in a future article.
Gregory Bartholomew
The words (parameters) passed to the script on the command line are available in the numbered variables $1, $2, $3, etc. If you want them all at once, you can use $*. So in your script, you would put “echo $*”. There is also a $@ that you may see used from time to time. It is similar to $* but it “tokenizes” the parameters a little differently. But that is a more advanced topic. 🙂
Dietmar
If you ever consider to look into bash, shell scripting or just the best Linux CLI tutorials of all times – ask your search engine for
Machtelt Garrels, Bash Guide for Beginners
and
Mendel Cooper, Advanced Bash-Scripting Guide
to be found here:
https://tldp.org/guides.html
For me this is the greatest IT – literature of all times.
A reference and a tutorial and an introduction and a specialists treasure trove in one.
Second to none.
Give it a try! Fell in love with bash scripting …