Bash Shell Scripting for beginners (Part 1)

Photo by N Bandaru on Unsplash

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.

Fedora Project community

32 Comments

  1. Athan

    The chmod command is inconsistent with what the targeted outcome is.

    • 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.

      • Wouldn’t it be better to change both (1) the command to

        chmod 755

        and (2) the output of

        ls -l

        to match the command?

        766

        permissions is weird (and insecure) because anyone can edit your script, even if you are the only one that can execute it.

        Or just

        chmod +x learnToScript.sh

        and you don’t have to worry about accidentally making your script world-writable.

  2. 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.

    • 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 is the OpenID page for pfrields.
        This page is primarily used internally
        • 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.

  3. 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!

  4. Daniel

    Good.

  5. Breno

    I would recommend

    nano

    instead of

    vim

    at a beginner level. Also,

    chmod +x

    sounds more intuitive for a beginner to me.

  6. 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,

    • Thank you I’ve added the specification into the next article for clarification on the keyboard.

  7. 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”

    • 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.

  8. 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.

  9. 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?

    • 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.

  10. Inci

    Great intro! Looking forward for part 2.

  11. edier88

    Great!
    This is really important for sysadmins and developers.
    Looking forward for the next parts!

  12. Stathis

    You might want to consider changing the shebang line of the script to

    #!/usr/bin/env bash

    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.

  13. Bryan

    Very nice article sir

  14. 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.

  15. 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.

    • 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. 🙂

  16. 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 …

Comments are Closed

The opinions expressed on this website are those of each author, not of the author's employer or of Red Hat. Fedora Magazine aspires to publish all content under a Creative Commons license but may not be able to do so in all cases. You are responsible for ensuring that you have the necessary permission to reuse any work on this site. The Fedora logo is a trademark of Red Hat, Inc. Terms and Conditions