Today in class while exploring wildcards, we found our way into the realm of shell scripting. This realm, a powerful if not initially mystical place, is a source of great power that can truly be a stepping stone to significant UNIX enlightenment.
We started with the basics of how to start a shell script, using the decisive “shabang”:
#!/bin/bash
As stated, things like comments are initiated with a “#” and are good from that point to the end of the current line.
And remember, the FDA recommends 5 servings of comments a day for a proper balanced diet.
Like many of the puzzles and quests you've encountered in UNIX thus far, you should hopefully be well aware that there are many solutions to any given problem. With that said, there is also plenty of ways to output something.
For now, the common basic output statement is that of: echo
echo is a built-in command to bash, that will display whatever string you pass to it. It is rather simple, having two common usages:
# Example 1: Output with newline echo "Hello, World!" # Example 2: Output without newline echo -n "Enter a value: "
In the case of the 2nd example, eliminating the newline will basically prevent the output from moving the cursor to the next line, so you can allow for more intuitive interactions with the user running the script.
To obtain input, we would use the “read” command, followed by a variable:
# Obtain input and store it in a variable called "stuff" read stuff
Variables in scripting languages are often simpler to utilize. Instead of worrying about declaring and determining their storage type and range/sign details, we just USE them when we need them.
Also of importance, when ASSIGNING a value to a variable (through input or direct assignment), we reference the variable merely by name. When we want to expand it and access its contents, we prefix the variable with a $ sign, which the shell uses as a “variable expansion” operator.
For example:
# Get input from the user, then output the input read value echo "You just entered $value" # Directly assign some values, then print them out myvar=12 stuff="more stuff" echo "$stuff is $myvar"
A very powerful feature present in bash shell scripting (and many other UNIX shell scripting environments) is that of command expansion, initiated with the use of the backquotes (` symbol, on the ~ key below ESC), you basically can insert something you could type on the command line, and the output of that will be what is actually substituted in place of the quoted string.
For example:
# Nicely display how many groups you are in echo "You are a member of `groups | wc -w` groups" # You can also assign that to a variable groupnum=`groups | wc -w` echo "You are a member of $groupnum groups"
Scripting has many of the regular programming constructs available for use.
We'll start with the venerable if statement:
# prompt and input a value, assume it is numeric, and display a message based on its value compared to 50 echo -n "Enter a number between 0 and 100: " read number if [ $number -lt 50 ]; then echo "$number is less than 50" elif [ $number -gt 50 ]; then echo "$number is greater than 50" else echo "$number is 50" fi
if statements begin with the familiar “if” keyword, and in this example make use of the “[” and “]” commands– yes, “[” and “]” are COMMANDS… they exist in /usr/bin, and have a manual page (be sure to check it out). if statements are followed by a “then” keyword; if you have an “else if” statement, it is represented as “elif”, and for else it remains simply “else”.
A key difference in bash's if statements is that they MUST be terminated by the ending “fi” keyword (which is simply “if” spelled backwards).
In this example, relational operators are represented as “-lt” for numeric less than, “-gt” for numeric greater than.. and the other common variants are available (check the bash manual page).
This is one of those instances where we make a distinction in the format of a variable's data… by default, it is pretty much treated as a string. But if we want it to be an integer, we just make sure to treat it as such when we want it to be that way.
Relational operators like “=”, “<”, “>” and company are treated as string comparisons. (Rumor has it that recent versions of bash blur this distinction, and you can actually get away with the familiar operators for both– but be mindful that if you do this and try to run your script on a sufficiently old version of bash, your script may crash and burn).
Things like input validation we'll endeavor to cover later, as a more advanced exercise.
A script is in some ways like a play, put on by eager thespians.
That said, it is important to ensure your script does not have any errors in it. Pretty much any element in your script can be manually typed out on the command-line for manual testing.. so don't be afraid to specifically test certain situations to make sure they make sense to you before blindly just adding them to your script wondering what may happen later.
When you are ready to see your script in action, save and exit from your file.
We must make our script executable, and we can do this merely by adding the “x” permission to the user field using the chmod command. NOTE that you do NOT need to “compile” your script.
Once your script is executable, run it by providing a relative path.
For example, let's say we have a script called “myscript.sh”…
lab46:~$ chmod u+x myscript.sh lab46:~$ ./myscript.sh
And you will be interacting with your script.
This week, I would like for you to write some scripts that do the following:
Put your final scripts on your week 6 journal entry inside dokuwiki file tags, as follows:
<file bash myscript.sh> #!/bin/bash # # myscript... # echo "blah" read var do stuff exit </file>
this will apply bash-style syntax coloring, and also provide downloadable links. Make sure to have all 8 of the requested scripts present in separate downloadable links on your journal page.
Be sure to ask questions. Questions are the only way you will effectively approach the answers and knowledge you seek.