Bash Script Examples (very very basic)

in #bash7 years ago (edited)

Bash Script Examples

As you may be able to guess from the name, a Bash script is a script that contains a series of Bash commands. Anything you can type in to bash can be put into a bash script.

Echo

Here's a stupidly simple Bash script:

#!/bin/bash
echo "Hello, world!"

The first line of the script is a comment, but it's a special one. The operating system will use this comment to determine what interpreter should be executed to run the content of the script.

The second line is the echo command, it's a built-in command that will simply repeat its arguments as output. Don't confuse this command with the /bin/echo executable, that's not the same thing, but they are similar. Note the quotes used around the string. These are not necessary in this case, but it's not a bad practice to use quotes when calling echo.

When executed, it would produce the following output:

Hello, world!

Simple (no argument) Functions

Here's a slightly more complicated Bash script, showing a function:

#!/bin/bash

# This is a bash script that shows how to create and call no-argument
# functions.
#

#
# This function just echoes "Hello, world!" to stdout.
hello(){
    echo "Hello, world!"
}

hello

This script produces the same output as the script before it. It features a few more comments. The comment explaining the overall purpose of the script is a good practice, but the comment explaining the purpose of the hello function is redundant because it says in English exactly what the extremely short and obvious one line it contains says in code.

Simple (single argument) Functions

Here's an updated version of the script that uses a function that takes arguments:

#!/bin/bash

# This is a bash script that shows how to create and call argument-accepting
# functions.

#
# This function echoes "Hello, ${1}!" to stdout.
hello(){
    local WHO=${1}
    echo "Hello, ${WHO}!"
}

hello world

This version of the script produces the same output as the previous scripts, but the object to whom it says hello can be customized by changing the value that is passed to hello. Put something other than world next to the call to hello and that's what will be in the output.

Notice that the hello function takes a parameter this time. The ${1} is a special variable that receives the value of the first argument that has been passed to the function. The keyword local creates a new variable called WHO in function hello that will only exist while the function is being called. It's a good practice to use local to scope variables to your functions to avoid accidentally over-writing a global function of the same name. Note that no quoting is needed to assign ${1} to the WHO variable.

If the last line of the script were to invoke hello thusly:

hello world of steem

The output would still look like the output from the previous functions. In this case, the world of steem is three separate arguments being passed to the hello function, but the function will only use the first argument because it only accepts one parameter.

Add quotes like so:

hello "world of steem"

And the output would be this:

Hello, world of steem!

STDOUT and STDERR and redirection

When stuff gets output it either goes to standard out or standard error. Generally stderr is where error messages go and stdout is where basic output goes.

Let's look at another example:

#!/bin/bash

# This is a bash script that illustrates writing to stdout and stderr.

# This function outputs whatever it's passed.
out(){
    echo ${@}
}

# This function output whatever it's passed to stderr.
err(){
    out ${@} >&2
}

out "Hello, output!"
err "Hello, error!"

If you're new to Bash you might wonder what unholy abomination this is, but it's actually pretty simple. The ${@} is a special variable that contains all the arguments that have been passed into the current context. From within a function, this means all the parameters passed to that function. If it were naked at the top level of the script (eg not in a function) then it would be all the arguments passed to that script.

In the err function there is a > sign. The > sign redirects whatever it reads from standard input and sends it out to whatever file descriptor follows it. In this case, the 2 is a special file descriptor that is standard error. So the result of the err function is to call the out function, and then whatever out produces it will then write to standard error.

The out function will write any of its arguments to standard out.

The err function will write any of it's content to standard error.

When this script is executed, it will write Hello, output! to standard out and it will write Hello, error! to standard error.

To test this, you would want to redirect standard error or standard out in order to confirm that it really does this.

So, run the script and you would see the following:

Hello, output!
Hello, error!

But that looks like what you would expect... so to see only the content from standard out, let's redirect standard error to a special file to get rid of it, assuming we named the script hello.sh, this is one way we could do that:

bash hello.sh 2>/dev/null

Placing that 2 before the pipe will redirect the standard error from the script, in this case to /dev/null

And the resulting output would be:

Hello, output!

Now, let's try it again, but redirect standard out, so all that is left is standard error:

bash hello.sh >/dev/null

That will look like the following:

Hello, error!

Notice that no number was provided this time, the default source of the redirection is standard out, so standard out is going to be written to /dev/null leaving only standard error to be displayed.

Now, these functions were extremely short and didn't really provide much of an advantage over just using echo directly, but they do enable one to quickly modify all output produced by the script to do something more, like, to prefix every line with a prefix, time stamp, or maybe change output to go to a file.

Return Values

Every line that executes produces a return value. This return value is an unsigned integer between 0 and 255.

Here's a script that returns 255:

#!/bin/bash

exit -1

If you run it, you wont see any output because it doesn't produce any. It just sets a return value or exit code. Return values are unsigned, so -1 will end up being set to 255. To see the return value, you can echo the special ? variable. After running this script, you could view the return value by typing echo $? but remember that ? is the return value of the last command run, so if you echo $? twice, the second time the return value will have changed to the return value of the previous echo command, so it wont be 255 anymore, it will be 0 After running this script, you could view the return value by typing echo $? but remember that ? is the return value of the last command run, so if you echo $? twice, the second time the return value will have changed to the return value of the echo command, so it wont be 255 anymore, it will be 0. Return codes are useful in making things like if statements, while loops, and other conditionally executed code.

Summary

And I just realized how late it is here, so I'm going to end this foray here. I'll continue it later, but since it was a kind of spur of the moment thing, I'm not sure what other topics I'll be covering or how long this series will be.

Here's a summary of what's been covered so far:

  • echo
  • simple no-argument functions
  • simple argument accepting functions
  • passing parameters (with and without quotes)
  • writing to standard out and standard error using redirection
  • special variables

Image source is, of course, Pixabay.

Sort:  

Since I can't edit the post anymore...

Errata:

It's a good practice to use local to scope variables to your functions to avoid accidentally over-writing a global function of the same name.

While technically not incorrect, that should have read:

It's a good practice to use local to scope variables to your functions to avoid accidentally over-writing a global variable of the same name.

Yes it seems that I never had a kindergarden bash class I just jumped right to changing permissions and moving around the hierarchy! I will be reading through this several times, so there may be more comments from me - thanks so much ;p

Inspire Competence

Do it, do it, do it!
Do it! Do it! Do it!
DO IT! DO IT! DO IT!

Congratulations @not-a-bird!
Your post was mentioned in the hit parade in the following category:

  • Pending payout - Ranked 6 with $ 58,74

Cool! Thanks!

If you're new to Bash you might wonder what unholy abomination this is, but it's actually pretty simple.

Oh my I really enjoy reading this - thank you for breaking it down to my level ;p