Article directory
-
- 14. Handling User Input
-
- 14.1 Command line parameters
- 14.2 Special parameter variables
- 14.3 Moving variables
- 14.4 Processing options
- 14.5 Option Standardization
- 14.6 Getting User Input
14. Handle user input
14.1 Command line parameters
Pass two parameters to addem 10 30
./addem 10 30
Read position parameters:$0
is the program name, $1
to $9
are the first to ninth parameters , the following parameters need to be ${10}
. Parameters are separated by spaces.
#!/bin/bash #Realize parameter reading and multiplication total=$[ $1 * $2 ] echo "The first param is $1" echo "The second param is $2" echo "The total value is $total" echo "The second param is ${10}"
Read script name:$0
passes the complete script path, use basename to get the script name without the path, so as to realize different functions according to different script names.
#!/bin/bash #Get the path name and script name of the script path_name=$0 script_name=$(basename $0) echo "The path of script is $path_name" echo "The script name is $script_name"
Test parameters: If the script is run without parameters, an error message will be generated, so it is best to add relevant parameter tests
Use -n
to test whether there is data in the parameter
#!/bin/bash #Check whether parameter 1 is normal input parameter if [ -n "$1" ] then echo "The first parameter you entered is $1 " else echo "You did not enter any parameters" the fi
14.2 Special parameter variables
Parameter Statistics
Some record command line parameters related variables, such as $#
is the total number of record command line parameters
#!/bin/bash #Test the total number of parameters, if there are two, do addition, otherwise an error will be reported if [ $# -ne 2 ] then echo "Usage: $(basename $0) a b" echo else total=$[ $1 + $2 ] echo echo "The total is $total" echo the fi
Since $#
records the total number, then ${$#}
should represent the last command line parameter, but this is not the case, ${! #}
is the correct way to get the last parameter variable.
#!/bin/bash #Test to get the last parameter echo "The last param is ${$#}" echo "The last param is ${<!-- -->!#}"
Crawl all data
$*
: All parameters are combined into a whole string
$@
: a separate string providing all parameters
#!/bin/bash # test $* and $@ count=1 for param in $* echo "\$* parameter #$count = $param" count=$[ $count + 1 ] done count=1 for param in $@ do echo "\$@parameter #$count = $param" count=$[ $count + 1 ] done
operation result:
It seems to be different from what we introduced, well, note that we wrote when traversing:
for param in $@
The difference between $*
and $@
can only be from "$*"
and "$@"
look out, i.e. write doing
for param in "$*" for param in "$@"
The final execution result is
14.3 Moving variables
When you don’t know how many parameters there are, you can use shift to transfer the value of the subsequent variable to the previous one, such as transferring $2
to $1
, while $1
is destroyed.
#!/bin/bash #simple test shift count=1 while [ -n "$1" ] do echo "Parameter #$count = $1" count=$[ $count + 1 ] shift done
Note that shift n
indicates how many parameters to move
14.4 Processing options
Handle simple options
Use case to extract parameters and determine whether it is an option
#!/bin/bash #Use shift to determine whether each parameter is an option in turn count=1 while [ -n "$1" ] do case "$1" in -a) echo "Found the -a option" ;; -b) echo "Found the -b option" ;; -c) echo "Found the -c option" ;; *) echo "$1 is not the option" ;; esac shift done
operation result:
Separate parameters and options
If a script uses both parameters and options, a special parameter is needed at this time to help identify which are parameters and which are options, here use “–” to separate.
#!/bin/bash #processing options count=1 while [ -n "$1" ] do case "$1" in -a) echo "Found the -a option" ;; -b) echo "Found the -b option" ;; -c) echo "Found the -c option" ;; --) shift #just to skip -- this parameter break;; *) echo "$1 is not the option" ;; esac shift done #Process parameters count=1 for param in "$@" do echo "Parameter #$count: $param" count=$[ $count + 1 ] done
Results of the:
Handle options with values
For example, in the following example, test1
should serve the option -a
./testing.sh -a test1 -b -c -d test2
You only need to insert relevant statements for reading parameters in the corresponding options
#!/bin/bash #processing options count=1 while [ -n "$1" ] do case "$1" in -a) echo "Found the -a option" ;; -b) param="$2" #Read the parameters after -b echo "Found the -b option with the param $param" shift;; #skip this parameter after -b -c) echo "Found the -c option" ;; --) shift #just to skip -- this parameter break;; *) echo "$1 is not the option" ;; esac shift done #Process parameters count=1 for param in "$@" do echo "Parameter #$count: $param" count=$[ $count + 1 ] done
operation result
The above command can only handle a single option, and has no ability to compound options, so the following getopt command is introduced
14.5 Option Standardization
getopt command
The format of the getopt command is as follows
getopt optstring parameters
optstring lists each command-line option letter you want to use in the script. Then, append a colon after each option letter that requires a parameter value. The getopt command parses the provided arguments based on the optstring you define.
For example:
#ab:cd indicates that there are 4 options, among which b needs to have parameters $getopt ab:cd -a -b test1 -cd test2 test3 -a -b test1 -c -d --test2 test3
If an undeclared parameter is used
$getopt ab:cd -a -b test1 -cde test2 test3 getopt: invalid option --e -a -b test1 -c -d --test2 test3
You can use -q
to ignore this parameter
$getopt -q ab:cd -a -b test1 -cde test2 test3 -a -b 'test1' -c -d -- 'test2' 'test3'
Using getopt in scripts
Think about it carefully, use getopt to get formatted input. But when executing in a script, I cannot execute the script with formatted input as input. So we use set --
, which will replace the original command with the formatted command.
#!/bin/bash #Process the input command, compared with the previous example code, only the following line is added set -- $(getopt -q ab:cd "$@") #processing options count=1 while [ -n "$1" ] do case "$1" in -a) echo "Found the -a option" ;; -b) param="$2" #Read the parameters after -b echo "Found the -b option with the param $param" shift;; #skip this parameter after -b -c) echo "Found the -c option" ;; --) shift #just to skip -- this parameter break;; *) echo "$1 is not the option" ;; esac shift done #Process parameters count=1 for param in "$@" do echo "Parameter #$count: $param" count=$[ $count + 1 ] done
operation result
But there is still a problem with this code, which cannot properly handle parameter values with spaces and quotes
Use more advanced optgets
getopts command format:
getopts optstring variable
optstring value:
Valid option letters are listed in optstring, and a colon is added if the option letter requires a parameter value. To get rid of the error message, put a colon before optstring.
getopts command:
Save the current arguments in a variable defined on the command line.
Two important environment variables
The OPTARG environment variable will save the parameter value after the option.
The OPTIND environment variable holds the parameter position in the parameter list that getopts is processing. This way you can continue processing other command line arguments after processing the options.
Sample code:
#!/bin/bash #Use getopts to get the option parameter segmentation, note that the option under the case is not -a), and the position transfer is realized after traversing all the parameters while getopts :ab:cd opt do case "$opt" in a) echo "This is -a option";; b) echo "This is -b option with value $OPTARG";; c) echo "This is -c option";; d) echo "This is -d option";; *) echo "Unknown option:$opt" ;; esac done #Skip the currently processed parameters shift $[ $OPTIND - 1 ] #Loop through parameters count=1 for param in "$@" do echo "Parameter $count: $param" count=$[ $count + 1 ] done
Option Standardization:
Linux commands already have specific meanings for key parameters, refer to
14.6 Get user input
Basic Read
Use read to get variable value from standard input
#!/bin/bash #-n means to get input without wrapping echo -n "Enter your name:" read name echo "Hello $name, welcome to my program." #read -p can output some prompt information to get a single input read -p "Please enter your age: " age days=$[ $age * 365 ] echo "That makes you over $days days old;" #read get multiple inputs read -p "Please enter your first and last: " first last echo "Checking data for $first, $last..." #If no variable is specified, all input will be saved in REPLY read -p "Enter the name which will save in:" echo "hello, welcome to $REPLY"
Timeout judgment
In order to prevent waiting all the time, use -t
to set the number of seconds to wait, and return a non-zero exit code after timeout.
You can also set -n num
to read the specified number of inputs and exit.
#!/bin/bash #Set the input of the timeout if read -t 5 -p "Please enter your name:" name then echo "Hello $name, welcome to my script" else echo "Sorry, too slow!" the fi #Set the specified number of inputs read -n1 -p "DO you want to continue [Y/N]?" answer case $answer in Y | y) echo "fine, continue on...";; N | n) echo "OK, goodbye" exit;; esac echo "This is the end of the script"
Read in hidden mode
The -s
option can prevent the data entered in read from appearing on the display
#!/bin/bash read -s -p "Enter your password: " pass echo echo "Is your password really $pass?"
Read from file
#!/bin/bash # reading data from a file # count=1 cat test | while read line do echo "Line $count: $line" count=$[$count + 1] done echo "Finished processing the file"