Linux Bash Scripting Part3 – Parameters and Options
So far, you’ve seen how to write Linux bash scripts that do the job without user inputs. Today we will continue our series about Linux bash scripting.
I recommend you review the previous posts if you want to know what we are talking about.
- 1 Read parameters
- 2 Check parameters
- 3 Counting parameters
- 4 Iterate over parameters
- 5 Shifting parameter variable
- 6 Bash scripting options
- 7 Separate options from parameters
- 8 Process options with values
- 9 Standard options
- 10 Getting user input using the read command
- 11 Reading password
- 12 Read files
Today we will know how to retrieve input from the user and deal with that input, so our script becomes more interactive.
To pass data to your shell script, you should use command line parameters.
$ ./myscript 3 5
Here we send two parameters (3 and 5) to the script. So how to read these parameters in our bash script?
Read parameters
The shell gives you some easy to use variables to process input parameters:
- $0 is the script’s name.
- $1 is the 1st parameter.
- $2 is the 2nd parameter.
The shell can read the 9th parameter, which is $9.
Let’s see those variables in action:
#!/bin/bash echo $0 # Script name echo $1 # 1st parameter echo $2 # 2nd parameter echo $3 # 3rd parameter
Check the results of the following command:
./myscript 5 10 15
Here is another example of how we can use two parameters and calculate the sum of them.
#!/bin/bash total=$(( $1 + $2 )) echo First passed parameter is $1. echo Second passed parameter is $2. echo Total is $total.
$ ./myscript 5 10
The parameters are not restricted to numbers; they could be strings like this:
#!/bin/bash echo Hello $1, how do you do
./myscript Adam
And the result is as expected.
What if our parameter contains a space, and we want to pass it as one value? I guess you know the answer from the previous posts. The answer is to use quotations.
If your script requires over nine parameters, you should use braces like this ${10}.
Check parameters
If you don’t pass parameters and your code is expecting it, your script will exit with an error.
That’s why we should use a Linux if statement to make sure that they exist.
#!/bin/bash if [ -n "$1" ]; then # If first parameter passed then print Hi echo Hi $1. else echo "No parameters found. " fi
Counting parameters
To get how many parameters passed, you can use this variable ($#).
#!/bin/bash echo There were $# parameters passed.
./myscript 1 2 3 4 5
How excellent is Linux bash scripting? This variable also provides a geeky way to get the last parameter. Look at this trick:
#!/bin/bash echo Last passed parameter is ${!#}
Iterate over parameters
The $* variable holds all the parameters as one value.
The $@ variable holds all the parameters as separate values so that you can iterate over them.
This code shows how to use them:
#!/bin/bash echo "The first variable \$* method: $*" echo "-----------" echo "The second variable \$@ method: $@"
The same result, but if you want to know the difference look at the following example:
#!/bin/bash total=1 for var in "$*"; do echo "\$* =======> #$total = $var" total=$(($total + 1)) done total=1 for var in "$@"; do echo "\$@ =======> #$total = $var" total=$(($total + 1)) done
Check the result to see the difference:
The result is pretty clear. You can use any method according to your needs.
Shifting parameter variable
The shift command moves every parameter variable to the left:
variable $3 ==> variable $2.
variable $2 ==> variable $1.
variable $1 ==> dropped.
variable $0 ==> (the script name) as it is.
You can use the shift command to iterate over parameters like this:
#!/bin/bash total=1 while [ -n "$1" ]; do # while loop starts echo "#$total = $1" total=$(($total + 1)) shift done
Here, we have a while loop checking $1 length. If $1 becomes zero, the loop stops. And the shift command is shifting all passed parameters to the left.
Careful when using the shift command, since you can’t recover the shifted parameter.
Bash scripting options
Options are single letters with a dash before it.
#!/bin/bash while [ -n "$1" ]; do # while loop starts case "$1" in -a) echo "-a option passed" ;; # Message for -a option -b) echo "-b option passed" ;; # Message for -b option -c) echo "-c option passed" ;; # Message for -c option *) echo "Option $1 not recognized" ;; # In case you typed a different option other than a,b,c esac shift done
$ ./myscript -op1 -op2 -op3 -op4
The above code checks for one of the correct options. If you typed one of them, the suitable commands would run.
Separate options from parameters
Sometimes you need to use options and parameters in the same script. You have to separate them. By doing this, you are telling the bash where the parameters are and where the options are.
We use the double dash (–) at the end of the options list. After the shell sees the double dash, it treats the remaining inputs as parameters and not as options.
#!/bin/bash while [ -n "$1" ]; do # while loop starts case "$1" in -a) echo "-a option passed" ;; # Message for -a option -b) echo "-b option passed" ;; # Message for -b option -c) echo "-c option passed" ;; # Message for -c option --) shift # The double dash which separates options from parameters break ;; # Exit the loop using break command *) echo "Option $1 not recognized" ;; esac shift done total=1 for param in $@; do echo "#$total: $param" total=$(($total + 1)) done
$ ./myscript -a -b -c -- 5 10 15
As you can see from the result, all the parameters after the double dash treated as parameters and not options.
Process options with values
When you dig deep into Linux bash scripting, sometimes you need options with additional parameter values like this:
./myscript -a value1 -b -c value2
There should be a way to identify any additional parameter for the options and be able to process it.
#!/bin/bash while [ -n "$1" ]; do # while loop starts case "$1" in -a) echo "-a option passed" ;; -b) param="$2" echo "-b option passed, with value $param" shift ;; -c) echo "-c option passed" ;; --) shift # The double dash makes them parameters break ;; *) echo "Option $1 not recognized" ;; esac shift done total=1 for param in "$@"; do echo "#$total: $param" total=$(($total + 1)) done
And if we run it with these options:
$ ./myscript -a -b test1 -d
From the results, you can see that we get the parameter for the -b option using the $2 variable.
Standard options
When you start your Linux bash scripting, you are free to choose which letter is suitable for your option.
However, some letters are commonly used in Linux programs.
And here is the list of the common options:
-a | List all items. |
-c | Get the count of items. |
-d | Output directory. |
-e | Expand items. |
-f | To specify a file. |
-h | To show the help page. |
-i | To ignore character case. |
-l | To list a text. |
-n | To say no for a question. |
-o | To send output to a file or so. |
-q | Keep silent; don’t ask the user. |
-r | To process something recursively. |
-s | Stealth mode. |
-v | Verbose mode. |
-x | Specify executable. |
-y | To say yes without prompting the user. |
It’s good to follow standards. If you work with Linux, many of these options may look familiar to you.
Getting user input using the read command
Sometimes you need data from the user while the bash scripting is running.
The bash shell uses the read command for this purpose.
The read command reads input from standard input (the keyboard) or a file descriptor and stores it in a variable:
#!/bin/bash echo -n "What's your name: " read name echo "Hi $name,"
We use the -n option to disable the newline so that you can type your text in the same line.
You can specify multiple inputs like this:
#!/bin/bash read -p "What's your name: " first last echo "Your data for $last, $first…"
If you don’t specify variables for the read command, it will save all incoming inputs in the REPLY variable.
#!/bin/bash read -p "What's your name: " echo Hello $REPLY,.
You can use the -t option to specify a timeout for input in seconds.
#!/bin/bash if read -t 5 -p "What's your name: " name; then echo "Hi $name, how are you?" else echo "You took much time!" fi
If you do not enter data for five seconds, the script will execute the else clause and print a sorry message.
Reading password
In Linux bash scripting, sometimes, you don’t want the user input to be displayed on the screen, like entering a password.
The -s option suppresses the output from appearing on the screen.
#!/bin/bash read -s -p "Enter password: " mypass echo "Your password is $mypass? "
Read files
The read command can read files one line on each call.
Now, if you want to get all file data, you can get the content using the cat command, then send it to the read command using while loop like this:
#!/bin/bash count=1 # Get file content then pass to read command by iterating over lines using while command cat myfile | while read line; do echo "#$count: $line" count=$(($count + 1)) done echo "Finished"
Or we can make it simpler by redirecting the file content to the while loop like this:
#!/bin/bash while read line; do echo $line done <myfile
We just pass the file content to the while loop and iterate over every line and print the line number and the content, and each time you increase the count by one.
I hope you find this post interesting. Keep coming back.
Thank you.
Mokhtar is the founder of LikeGeeks.com. He is a seasoned technologist and accomplished author, with expertise in Linux system administration and Python development. Since 2010, Mokhtar has built an impressive career, transitioning from system administration to Python development in 2015. His work spans large corporations to freelance clients around the globe. Alongside his technical work, Mokhtar has authored some insightful books in his field. Known for his innovative solutions, meticulous attention to detail, and high-quality work, Mokhtar continually seeks new challenges within the dynamic field of technology.
Good stuff
Thanks 🙂
Hello.
I have a question about “Reading password” part:
– read command makes the text color as the background color of the shell.
I thought it works in a different way, it hides all that you typed. Otherwise you could select all that you typed and copy your hidden text. Can someone clarify this part? 🙂
Thank you!
Correct.
This is because the -s only hides what you entered by making the text color as the terminal background color as mentioned above.
If “-s” only changes color I can select typed by mouse and copy?
No, the result is suppressed too while using -s.
Ok, thank you! 🙂
You are welcome!
“`#!/bin/bash
while [ -n “$1” ]; do # while loop starts
case “$1” in
-a) echo “-a option passed” ;;
-b)
param=”$2″
echo “-b option passed, with value $param”
shift
;;
-c) echo “-c option passed” ;;
–)
shift # The double dash makes them parameters
break
;;
*) echo “Option $1 not recognized” ;;
esac
shift
done
total=1
for param in “$@”; do
echo “#$total: $param”
total=$(($total + 1))
done“`
Don’t you have to shift twice after option b with value was passed?
Why? I didn’t understand your question.