Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Shell command line arguments (getopt and getopts)

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/02 Report--

Here is the previous article, and this part is the foundation:

Https://blog.51cto.com/steed/2443313

Getopt command

Using the getopt command, you can parse any command-line options and parameters, but the usage is complex. The command usage of getopt is as follows:

Getopt-- help usage: getopt optstring parameters getopt [options] [- -] optstring parameters getopt [options]-o |-- options optstring [options] [- -] parameters option:-a,-- alternative allows long options to start with-h,-- help this short usage guide-l,-- long options to be identified by longoptions-n -- the program name to which name reports the error-- o,-- short option to be recognized by options-- Q,-- quiet prohibits error reporting by getopt (3)-- Q,-- quiet-output has no normal output-s,-- shell sets shell reference rule-T -- test test getopt (1) version-u,-- unquoted does not reference output-V,-- version output version information $

There are three formats for usage, all of which will be used below.

Easy to use on the command line

Getopt optstring parameters

The first part is the command name.

The second part, optstring (option string), is the format that this command parses.

The third part, parameters (the parameter of the getopt command), is what needs to be parsed.

Therefore, getopt parses the parameters to the appropriate options and parameters as set by optstring. Refer to the example to understand:

$getopt ab:cd-ad value1-b best1 value2 value3-a-d-b best1-- value1 value2 value3 $

Mainly understand the meaning of ab:cd.

All the short options are defined here, and four letters represent four options. The colon after b indicates that this option requires an argument. If you do not give option b an argument, an error will be reported:

$getopt ab:cd-ad value1-bgetopt: the option requires a parameter-- b-a-d-- value1 $

If a double dash line is added, then what follows the no wheel is treated as a parameter rather than an option:

$getopt ab:cd-- ad value1-b best1 value2 value3-ad value1-b best1 value2 value3 $getopt ab:cd-ad value1-b best1 value2 value3-a-d-- value1-b best1 value2 value3 $

This is still the first format for command usage, and the double dash is part of the parameters content.

The content before the position of the double dash line is parsed according to the setting of optstring, and the content after that is regarded as a parameter. Even if there is a similar option, it is recognized as a parameter.

The first format is also different from the second and third in function. The parameters output here are unquoted. The parameters output in the other two formats are in quotation marks.

The important difference is not in quotation marks, but this usage does not support the handling of parameter values with spaces and quotation marks. It treats spaces as parameter delimiters rather than both as one parameter based on double quotes.

Support for long option

Refer to the example above, plus support for the long option. Examples of using long options are as follows:

Getopt-o ab:cd-- long arga,argb:,argc,argd-- ad-b best-- argd value1 value2-a-d-b 'best'-- argd--' value1' 'value2'$

This is the third format for command usage.

-o means to define short options

-- long is actually-- longoptions, but you can recognize it by omitting any letter program. All the content should be connected and there can be no spaces. After the definition is finished, it is separated by double dashes, followed by parameters.

The program name referenced by the error report

I have tried to report parsing errors once before:

$getopt ab:cd-ad value1-bgetopt: the option requires a parameter-- b-a-d-- value1 $

The getopt error is reported here, and you can replace this default content. It is usually replaced with the name of the script that is executed.

Here, using the second format of command usage, put both optstring and parameters after the double dash line:

Getopt-- ab:cd-ad value1-b best1-a-d-b 'best1'--' value1'$

This allows you to add the option of the getopt command in front of the double dash line, where you want to specify the-n option:

$getopt-n test.sh-- ab:cd-ad value1-b test.sh: option requires a parameter-- b-a-d-- 'value1'$

The error seen here is that the name has been replaced.

In the script, you can use $(basename $0) or directly use\ $0.

Prohibit error reporting

There is also a-Q parameter that forbids error reporting, and options and parameters that parse errors are discarded:

$getopt-n test.sh-Q-- ab:cd-ad value1-b-a-d-'value1'$ optional parameters

There is also an optional parameter that uses two colons. This option can have one or zero parameters:

$getopt-o a::bc:-l arga::,argb,argc:-avalue1-- arga value2-a'--arga''--'value1'' value2'$ getopt-o a::bc:-l arga::,argb,argc:-avalue1-- arga=value2-a 'value1'-- arga' value2'-- $

The parameter passed in the first execution is incorrect. Because it is an optional parameter, there must be no space between the parameter and the value, otherwise there will be ambiguity. Must be concatenated to be considered a parameter of the previous option. Otherwise, it will be regarded as an independent parameter.

Summary

Rules for the option string specified by the options of the getopt command:

Short options, each character represents an option long option, each string represents an option, separate the option with a comma followed by a colon, indicating that the option requires a parameter option followed by two colons, indicating that the option has an optional parameter (one or zero parameters). There can be no space between the parameter and the value of the optional parameter, the short option is directly connected, the long option plus the equal sign is used in the script to use getopt

You can now use the getopt command to parse the command-line arguments into a regular format according to the specified format. And in the parsing process, the wrong format of the parameters can also be found and reported.

The next step is to use the parsed parameters in the script after the getopt command.

Set command

To use getopt in your script. First, use the getopt command to generate a formatted version to replace the existing command-line options and parameters. The set command is required.

The set command can handle various variables in shell. Do not expand, here is only one option of this command, double dash line (- -). The effect is to replace the command line arguments with the parameter values of the set command.

This method then passes the command line arguments of the original script to the getopt command execution, and then passes the output of the getopt command to the set command, replacing the original command line arguments with the getopt formatted command line arguments:

Set-$(getopt ab:cd "$@")

Now the value of the original command line argument variable is replaced by the output of the getopt command. And getopt has formatted the command-line arguments for us.

Direct use

On the basis of the previous script, you can use it directly by adding a line of code at the beginning:

Set-$(getopt a:b:s:u "$@")

After adding this sentence, you let the subsequent code handle the parameters returned by getopt, rather than the command-line arguments when the command is invoked.

Verify the effect:

$. / format.sh-u-an after-b befor value1 value2 value3BEFOR_VALUE1_AFTERBEFOR_VALUE2_AFTERBEFOR_VALUE3_AFTER$. / format.sh-u-an after-b befor value1 "value2 value3" value4BEFOR_VALUE1_AFTERBEFOR_VALUE2_AFTERBEFOR_VALUE3_AFTERBEFOR_VALUE4_AFTER$

The second command does not handle parameters with spaces because the first format of getopt is used here.

To handle spaces, you need to use the second format (or the third) and change the command to the following:

Set-$(getopt-a:b:s:u "$@")

Simply add a double dash line in front of it. This statement is wrong and will be modified later.

Let's verify it again:

$. / format.sh-u-an after-b befor value1 "value2 value3" value4'BEFOR'_'VALUE1'_'AFTER''BEFOR'_'VALUE2_'AFTER''BEFOR'_VALUE3'_'AFTER''BEFOR'_'VALUE4'_'AFTER'$

Using the second and third formats, quotation marks are used to define the contents of the parameters. But quotation marks interfere with the set command.

Use the eval command

There is a new problem here, not only is the space not handled correctly, but the output also has additional quotation marks. Put aside the problem of spaces for a while, here you need to use the eval command to solve the new problem.

The eval command is used to read and execute the following content as a single command, which is used to handle the escape characters of the parameters generated by the getopt command.

With regard to the eval command, there is another use scenario. Sometimes the strings spliced in the script look correct even if they are printed out. And directly copy and paste in the interactive interface can also be read correctly and run as a command. But it cannot be executed in a script. At this point, you can use the eval command to solve the problem. It can execute a string as a command.

When a complex command is stitched together through various references and judgments in a script, sometimes it cannot be executed. At this time, you can directly assign and paste to the exchange world for an interview. If the splicing result itself is fine, then after adding the eval command, it should be able to run.

The modification command is as follows:

Eval set-$(getopt-a:b:s:u "$@")

$. / format.sh-u-an after-b befor value1 "value2 value3" value4BEFOR_VALUE1_AFTERBEFOR_VALUE2 VALUE3_AFTERBEFOR_VALUE4_AFTER$

The first format plus the eval command is not a problem, so it can be used without a brain.

Solve the space problem

As long as the second or third format of getopt is used correctly, the problem of parameters containing spaces is solved. Take a look at a bar.

Parameter parsing error and exit

When executing the command, use the wrong parameters, and the current effect is as follows:

$. / format.sh-u-w-an after-b befor value1 "value2 value3" value4getopt: invalid option-wBEFOR_VALUE1_AFTERBEFOR_VALUE2 VALUE3_AFTERBEFOR_VALUE4_AFTER$

The parsing found a problem and reported it, but the script did not terminate, but continued execution. If you want to determine the parsing error, you need to use\ $? Parameters. Then exit the script with the exit command.

Use\ $directly here? The result of the parameter parsing error cannot be obtained. Because the result at this time is the execution of the set command (or it may be the eval command), and getopt is the previous command.

To solve this problem, we should first execute the getopt command and make a judgment. Then call it again with set, and you can directly use the result of previous execution:

Getopt_cmd=$ (getopt-n $(basename $0)-a:b:s:u "$@") [$?-ne 0] & & exit 1eval set-"$getopt_cmd"

The definition of the name when the error is reported is also added here. When exit exits, you should also specify that the exit status is non-0, because it is a running error.

Verify the effect:

$. / format.sh-v-an after-w-bformat.sh: invalid option-- vformat.sh: invalid option-- wformat.sh: option requires a parameter-- b $echo $? 1 $

Now when there is a problem with the parsing, it will quit directly.

Long options and optional parameters are added here.

An extra parameter-m,-- mark is added because it specifies which connector to use:

Connect directly by default, do not use connection symbols plus options, use underscore connections as options by default, and use parameters to connect

There are many parameters, add-h,-- help option to print parameter description.

The complete code is as follows:

$cat format.shalloxample binbinhambashmark= "" # concatenation symbol prefix= "" # prefix base= "test" # default string suffix= "" # suffix upper=off # whether uppercase # shows that this is an array variable In fact, there is no need for declare-a names # to format all the original string # printed help help_str= "parameter description:-h,-- help: print help-m,-- mark [connector]: use a connector. The default is an underscore (_). You can specify-a,-- after string: add the suffix-b,-- befor string: add the prefix-s,-- string string: specify the middle string The default is "test"-u,-- upper: all uppercase output "# parse the command line parameter getopt_cmd=$ (getopt-o m::ha:b:s:u-- long mark::,help,after:,befor:,string: Upper-n $(basename $0)-"$@") [$?-ne 0] & & exit 1eval set-"$getopt_cmd" # parsing option while [- n "$1"] do case "$1" in-m |-- mark) case "$2" in ") mark=" _ "shift ; *) mark= "$2" shift;; esac;;-h |-- help) echo-e "$help_str" exit;;-a |-- after) suffix= "$2" shift -b |-- befor) prefix= "$2" shift;;-s |-- string) base= "$2" shift;;-u |-- upper) upper=on;;--) shift break;; *) echo "$1 is not an option" exit 1 # Discovery unknown parameters Directly exit the esac shiftdone# parsing parameter while [- n "$1"] do names= ("${names [@]}"$1") shiftdonenames [0] = ${names [0]:-$base} for name in "${names [@]}" do # add the prefix and suffix output= "${prefix:+$ {prefix} ${mark} ${name} ${suffix:+$ {mark} ${suffix}" # determine whether to output all uppercase if [$upper = on] then output=$ {output ^ ^} fi # output result echo "$output" done$

Verify the effect:

$. / format.sh-an after-b beforVALUE1 "VALUE2 VALUE3" VALUE4beforVALUE1afterbeforVALUE2 VALUE3afterbeforVALUE4after$. / format.sh-an after-b befor-- mark befor_test_after$. / format.sh-an after-b befor-- mark= "| |"-uBEFOR | | TEST | | AFTER$. / format.sh-an after-b befor-- mark= "| |-u-- help parameter description:-h,-- help: print help-m,-- mark [connector]: use the connector. The default is an underscore (_). You can specify-a,-- after string: add the suffix-b,-- befor string: add the prefix-s,-- string string: specify the middle string, default is "test"-u,-- upper: all uppercase output $

It's enough to have getopt. By the way, getopts will be brief.

Getopts is slightly less functional, but it is more advanced, easier to use, and requires less code.

Getopts command

It is an internal command of Bash.

Its advantages are:

The Shell variable getopts defined in POSIX can be easily set up for parsing without the need for an external program to handle the position parameters.

Long options are not supported:

Getopts cannot parse GUN-style long options (--long) or XF86-style long options (- long)

Getopt generates only one output after processing options and parameters. We also need to use set to complete the delivery work.

Getopts can work tacitly with existing shell parameter variables. Each call processes only one parameter detected on the command line at a time. After processing, it exits and returns an exit status code greater than 0. This makes it very convenient to use in the while loop.

Basic usage

Getopts uses the following three variables:

OPTIND: the index that holds the next parameter to be processed. This is how getopts remembers its state during the call.

OPTERR: value is 0 or 1. Indicates whether Bash should display an error message generated by getopts.

The basic syntax of the getopts command:

Getopts option string name [parameter]

Option string (OPTSTRING): what options will getopts have and which will have parameters (followed by a colon after the option)

Name (VARNAME): getopts assigns the found options to the variable with this name

Parameters (ARGS): in general, by default, getopts parses all parameters when the script is called. If this parameter is executed, getopts does not parse the parameters passed to the script, but instead parses the parameters here.

Getopts does not move variables. After all the options have been processed, the command stops and leaves the parameters to us to continue processing. At this point, you can use the shit command with the value of OPTIND to move to the position of the first parameter:

Shift $[$OPTIND-1] error reporting mode

The getopts command supports two error reporting modes:

Detailed error reporting mode suppresses error reporting mode

For scripts in the product, suppressing error reporting mode is recommended.

Detailed error reporting mode

In detailed error reporting mode, if getopts encounters an invalid option, the value of VARNAME is set to the question mark (?) and the variable OPTARG is not set. If the required parameter is not found, the value of VARNAME will also be set to the question mark, the variable OPRARG will not be set, and an error message will be printed.

Suppress error reporting mode

In suppressed error reporting mode, if getopts encounters an invalid option, the value of VARNAME is set to the question mark (?) and the variable OPTARG is set to the option character. If the required parameter is not found, the value of VARNAME is set to a colon (:), and the variable OPTARG contains option characters.

To use suppressed error reporting mode, simply set the option string (OPTSTRING) to start with a colon when calling getopts. The following example uses the constant error reporting mode.

Sample code

The suppressed error reporting mode is used here, so you need to analyze and report the parsing errors yourself. It's all in the code:

$cat say_hello.sh #! / bin/bashdefaultname= "nobody" # default name declare-a names # an array of names hello= "hello" # greeting end= "!"# ending content tittle=off # is capitalized # parsing option while getopts: n:h:e:t optdo case" $opt "in n) defaultname=" $OPTARG " H) hello= "$OPTARG";; e) end= "$OPTARG";; t) tittle=on;;:) # No parameter echo "This option-$OPTARG requires an argument." Exit 1;) # found invalid option echo "- $OPTARG is not an option" exit 2 The esacdone# parsing parameter shift $[$OPTIND-1] # moves to the position of the first parameter # this time iterate through for arg in "$@" do names= ("${names [@]}"$arg") donenames [0] = ${names [0]:-$defaultname} for name in "${names [@]}" do ["$tittle" = on] & & output= "${hello^} ${name ^} $end" | | output= "

The verification is performed as follows:

$. / say_hello.sh hello nobody! $. / say_hello.sh-n adamhello adam! $. / say_hello.sh-n adam-h hi-e. -tHi Adam. $. / say_hello.sh-h hi-e -t adam bob clarkHi Adam .Hi Bob .Hi Clark. $. / say_hello.sh-a-h hi-e. -t adam bob clark-an is not an option$. / say_hello.sh-hThis option-h requires an argument.$

Options and parameters cannot be mixed:

$. / say_hello.sh adamhello adam! $. / say_hello.sh adam-thello adam! hello-t! $

Double broken lines are supported:

$. / say_hello.sh-t adamHello Adam! $. / say_hello.sh-t-- adamHello Adam! $

In comparison, it is much easier to use than getopt, but it is also much worse in functionality, and the optional parameter (double colon::) should not be supported. In addition, if you are familiar with getopt, each step is controlled by your own code. Getopts simplifies a lot of things, such as not calling shift movement variables.

Here are some options and meanings that are often used in command line options:

Option description-a shows all objects (show hidden)-c generates a count-d specifies a directory-e extends an object-f specifies a file for reading data-h displays help for commands-I ignore text case-l produces a long format version of the output-n uses non-interactive mode (batch)-o redirects all output to the specified output file-Q to Run in quiet mode-r recursively process directories and files-s run in quiet mode-v generate detailed output-x exclude an object-y answer all questions yes

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report