By: Daniel Farina | Updated: 2018-12-05 | Comments (2) | Related: > SQL Server on Linux
Problem
You are a SQL Server Database Administrator and you are starting to use SQL Server on Linux. As you have probably found out, there are several administrative tasks that you need to do differently on Linux versus Windows. In this tip I will show you the different ways you can use Bash scripting to display messages and also how to catch user input.
Solution
When you want to build a Bash script (or any other kind of script) the first thing you need to know is how the script is going to be used. Without too much thinking we can define two categories of scripts: those that run in the background like Cron jobs and those that require user input, like an installation script.
If your goal is to create a script that runs in the background, you can't catch any user input and must rely on getting everything for your script to work from a configuration file. We will see how to read from files in another tip. Also, you should probably re-think about writing to the console for these background scripts and consider writing to a text file for logging instead.
If your goal is to write an interactive script that can be able to display information and receive user input, then I will show how this can be done in this tip.
Working with Interactive Bash Scripts
When we aim to give some informative message to the console, Bash gives us two tools we can take advantage of. If you have been reading the tips in this series you already know one, which is the echo command. The other one is the printf function. If you ever worked with C or C++ languages you will find this easy. But if you haven't, after reading this tip you will see it is easy to do.
The Bash echo Command
If you have been reading my previous tips in this series you already saw how to use the echo command to display basic output to the console. But this command allows more complex usage depending on which parameter you pass to it.
In the next table I have copied the parameters available from the echo command page.
Parameter | Description |
---|---|
-n | Don't write the trailing newline. |
-e | Enable interpretation of backslash escapes. This is the most important and the one I will get covered. |
-E | Disable interpretation of backslash escapes which is the default behavior. |
Let's consider the following script:
#!/bin/bash Variable1="Hello" Variable2="World" echo $Variable1 echo $Variable2 echo -n $Variable1 echo -n $Variable2
On the next screen capture you will see the output of that script execution. Notice that the addition of the –n parameter suppressed the new line.
The –e parameter of the echo command allows us with the possibility to change the way we write our messages to the console by using escape sequences. In the next table I wrote a list of each escape sequence and its meaning. All the ASCII codes are expressed in decimal notation.
Escape Sequence | Description |
---|---|
\a | Writes the ASCII 07 character to the console which is known as Alert or Bell. Basically, it plays an alert sound on your speaker. |
\b | Writes one backspace character (ASCII 08) to the console. The result is like pressing the backspace key in your keyboard. It deletes the character before it. |
\c | It produces no further output. Use this when you want to hide the output of what is after the \c. |
\e | Writes the escape character (ASCII 27) to the console. It's like pressing the escape key in your keyboard. |
\f | Writes the form feed character (ASCII 12) to the console |
\n | Starts writing in a new line |
\r | Performs a carriage return. |
\t | Writes a Horizontal tab (like pressing the tab key). |
\v | Writes a Vertical tab. |
\\ | Writes a backslash. |
\0NNN | The eight-bit character whose value is the octal value NNN (zero to three octal digits) |
\xHH | The eight-bit character whose value is the hexadecimal value (one or two hexadecimal digits). |
Echo Examples
Now I will give you a few examples using an escape sequence.
In the next script I show you how the \c escape sequence suppresses the output of the text that follows and additionally how to write a vertical tab with the \v escape sequence.
#!/bin/bash echo -e "Hello \c World!" echo echo echo -e "Hello\v World!"
In the next example, I will show you how to write characters by using hexadecimal and octal notation. You can use the following link to get an ASCII table in decimal, hexadecimal and octal numeric systems: http://www.asciitable.com/.
#!/bin/bash #H 48 110 #e 65 145 #l 6C 154 #l 6C 154 #o 6F 157 echo -e "\x48\x65\x6C\x6C\x6F World!" echo -e "\0110\0145\0154\0154\0157 World!"
The Bash printf Command
This command is an improved version of echo, because it provides a method for printing formatted text like the C/C++ printf function does.
The syntax of this command is as follows:
printf [FORMAT] [ARGUMENT_1] …[ARGUMENT_n]
Basically FORMAT contains the static text and variables or constants you want to print to screen formatted with any of the available format codes and modifiers. In case you want to write variables or constants you should not include them in the format section. Instead you have to specify the format which you want to be used to print each of those. After setting the format you have to include as arguments the variables or constants you like to print in the same order you specified their format. As a side note, notice that both format and arguments are not separated by commas.
Format | Description |
---|---|
%b | Print the associated argument while interpreting backslash escapes in there |
%q | Print the associated argument shell-quoted, reusable as input |
%d | Print the associated argument as signed decimal number |
%i | Same as %d |
%o | Print the associated argument as unsigned octal number |
%u | Print the associated argument as unsigned decimal number |
%x | Print the associated argument as unsigned hexadecimal number with lower-case hex-digits (a-f) |
%X | Same as %x, but with upper-case hex-digits (A-F) |
%f | Interpret and print the associated argument as floating point number |
%e | Interpret the associated argument as a number in double precision, and print it in exponential (<N>±e<N>) format |
%E | Same as %e, but with an upper-case E in the printed format |
%g | Interprets the associated argument as double, but prints it like %f or %e |
%G | Same as %g, but print it like %E |
%c | Interprets the associated argument as char: only the first character of a given argument is printed |
%s | Interprets the associated argument literally as string |
%n | Assigns the number of characters printed so far to the variable named in the corresponding argument. Can't specify an array index. If the given name is already an array, the value is assigned to the zero elements. |
%a | Interprets the associated argument as double, and prints it in the form of a C99 hexadecimal floating-point literal. |
%A | Same as %a, but print it like %E |
%(FORMAT)T | outputs the date-time string resulting from using FORMAT as a format string for strftime(3). The associated argument is the number of seconds since Epoch, or -1 (current time) or -2 (shell startup time). If no corresponding argument is supplies, the current time is used as default |
%% | No conversion is done. Produces a % (percent sign) |
In the following script you can take a look at some examples on the usage of the format wildcard.
Printf Escape codes
Just like the echo command, printf also has escape codes. In order to maintain compatibility, printf keeps the same escape codes than the echo command, but adds a few more that I will enumerate next.
Escape Sequence | Description |
---|---|
\'' | Writes a " quote. |
\? | Writes a "?" sign. |
Printf Examples
I will give a few examples showing the usage of printf.
Take a look at the next script when I show you how to format numbers. Notice that I use \n to start the next line in a new line.
#!/bin/bash MyVar=-112450000000000 printf "MyVar as signed decimal number: %d\n" $MyVar printf "MyVar as floating point number: %f\n" $MyVar printf "MyVar as double precision number: %e\n" $MyVar printf "MyVar as double precision number: %E\n" $MyVar printf "MyVar as double precision number: %g\n" $MyVar printf "MyVar as double precision number: %G\n" $MyVar printf "MyVar as unsigned decimal number: %u\n" $MyVar printf "MyVar as C99 hexadecimal floating-point number: %u\n" $MyVar printf "MyVar as a character: %c\n" $MyVar printf "MyVar as a string: %s\n" $MyVar printf "Here is a percentage sign: %%\n"
On the next image you can see the execution of the previous script.
When to use printf instead of echo?
Printf is ideal when you need to display formatted text or a statement composed with many variables.
Using the Read Command to Catch User Input
In order to write an interactive script, the scripting language must give you the possibility to grab user input. Bash is not an exception. It provides us with the read command. This command reads one line from the console (the standard input) or any file descriptor you pass as a parameter. I will cover file descriptors in another tip, but for now think that everything in Linux is a file. Yes, even the console as file which is /dev/tty. As homework, try to write something to that file for example by running the following command.
ls > /dev/tty
The read command has the following syntax.
read [options] VAR1 VAR2 ... VARN
The options are described in the table below. VAR1 … VARN are the destination variables for each word separated by a space character of the line. In case you only use one variable, it will get all the words.
Option | Description |
---|---|
-a ArrayName | Each input word is assigned to an item of a given array. |
-d DELIM | The first character of DELIM will be used as the end of the line instead of CRLF. |
-e | The GNU Readline command (https://en.wikipedia.org/wiki/GNU_Readline) is used to catch the line. |
-n NCHARS | NCHARS means the number of characters you want to read from the input. For example, if NCHARS is two, after you press two keys on your keyboard the read command will end and grab only those two characters. |
-p PROMPT | Shows the content of PROMPT (which usually is a string) before reading the input message. You can use this in case you want to print a message like "enter your folder:" and then grab the input. |
-r | Makes the backslash character (\) to not act as an escape character. |
-s | When this option is used the user input is not show to the screen. This is ideal if you want to retrieve a password. |
-tTIMEOUT | If the user didn't enter a value during the seconds defined in TIMEOUT, you will receive an error message. |
-u FD | Instead of reading the input from the console uses the file descriptor specified in FD. |
Read Command Examples
The next script prompts the user for his name and saves it in a variable.
#!/bin/bash read -p "Enter your Name:" Name echo "Your name is " $Name
On the next screen capture you will see the execution of the previous script.
In the next example I use the –d option to change the end of line character to ";" instead of the default CRLF.
#!/bin/bash echo "Enter the following personal info. Finish with semicolon (;)" echo "Name" echo "Surname" echo "Address" read -d ";" Info printf "\nYou entered:" printf "%s\n" $Info
The next screen capture shows the results of the execution of the previous script.
As you may guess, this is not very useful. It would be awesome if we could parse each data element in an array. The good thing is that we can do that! Take a look at the following script.
#!/bin/bash declare -a MyArray echo "Enter the following personal info. Finish with semicolon (;)" echo "Name" echo "Surname" echo "Phone" read -a MyArray -d ";" printf "\nYou entered:" printf "%s\n%s\n%s\n" ${MyArray[0]} ${MyArray[1]} ${MyArray[2]}
Next Steps
- Stay tuned for the next tips in this series.
- Are you new on SQL Server running on Linux? You must read this tip: Getting Started with SQL Server on Linux.
- Are you a SQL Server DBA new to Linux? Here you will find 7 Things Every SQL Server DBA Should Know About Linux.
- On the next tip you will find the Top 10 Linux Commands for SQL Server DBAs.
- Take a look at SQL Server on Linux Tips Category.
About the author
This author pledges the content of this article is based on professional experience and not AI generated.
View all my tips
Article Last Updated: 2018-12-05