What is the double dash in this bash script excerp

2020-03-28 16:24发布

I'm looking at an excerpt of bash and I'm trying to understand what exactly is happening here, particularly in the COMPREPLY assignment:

 case "$cur" in
    -*)
    COMPREPLY=( $( compgen -W '-a -d -f -l -t -h --aoption --debug \
                               --file --log --test --help --' -- $cur ) );;
#   Generate the completion matches and load them into $COMPREPLY array.
#   xx) May add more cases here.
#   yy)
#   zz)
  esac

I understand we're assigning a value to COMPREPLY here based on the output of compgen, but what exactly is -- doing in this assignment? Also, why the double semi-colon?

标签: bash
3条回答
▲ chillily
2楼-- · 2020-03-28 16:28

The meaning of -- really depends on the program you are executing. In this example compgen. Check the documentation of this program, it should be explained there.

A common convention that is not necessarily always followed is to treat everything after -- as arguments, and do not try to parse as options or flags. As a concrete example, consider the case of running the GNU ls command to get a detailed listing of a file named -t. Running ls -l -t will treat -t as an option (order output by time), not as a filename argument. The solution is ls -l -- -t, this way ls will not try to parse the arguments after --. This is just a convention and not all programs may follow it. Note also that I wrote GNU ls not just ls, because other implementations may behave differently.

查看更多
我想做一个坏孩纸
3楼-- · 2020-03-28 16:34

compgen is a bash builtin command, and the man pages say:

Unless otherwise noted, each builtin command documented in this section as accepting options preceded by - accepts -- to signify the end of the options.

Since $cur is a variable that contains options (starting with -), the -- is required (as mentioned in the man pages) to make a distinction between compgen options and input to be processed.

The following command is turning the option --d in --debug:

compgen -W '-a -d -f -l -t -h --aoption --debug --file --log --test --help --' -- --d
--debug

If you remove the separator --, the command throws an error, because compgen doesn't have any option starting with --d:

compgen -W '-a -d -f -l -t -h --aoption --debug --file --log --test --help --' --d
-bash: compgen: --: invalid option
compgen: usage: compgen [-abcdefgjksuv] [-o option]  [-A action] [-G globpat] [-W wordlist]  [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]

The ;; is a separator used in the case, esac statement to terminate in your example the section started with -*). Look at bash man pages for Compound Commands to get more info.

查看更多
该账号已被封号
4楼-- · 2020-03-28 16:54

The double dashes end the argument portion in getopt_long. From the manual.

The special argument "--" forces an end of option-scanning regardless of the scanning mode.

https://linux.die.net/man/3/getopt_long

The double semi colons end a case branch.

查看更多
登录 后发表回答