Bash Script Examples (very very basic)
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.
Since I can't edit the post anymore...
Errata:
While technically not incorrect, that should have read:
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
Oh my I really enjoy reading this - thank you for breaking it down to my level ;p