How the Docker CLI interprets the parameters

Source: Internet
Author: User
Tags deprecated

Then the previous Docker command attach source analysis, continue to go

First look at Prase's overall code:

such as docker attach xxxid -> xxxid = argumentsfunc  (Fs *FlagSet)  parse (arguments []string)  error {fs.parsed = true //Play logo, function:parsed  Reports whether fs. Parse has been called, look at this step. No Fs.args = arguments for {seen, name,  err := fs.parseone ()//key is the execution of the Parseone function, seen returns true to continue If seen {continue}if err  == nil {break}if err == errretry {if len (name)  > 1  {err = nil//strings. Split ("123", "") = "1 2 3"   convert string to an array {1,2,3}for _, letter := range  Strings. Split (name,  "")  {fs.args = append ([]string{"-"  + letter}, fs.args ...) Mark "-" and Continue Parseoneseen2, _, err2 := fs.parseone () if seen2 {continue}if  ERR2 != NIL {ERR = FS.FAILF ("FLAG PROVIDED&Nbsp;but not defined: -%s ",  name) break}}if err == nil {continue}}  ELSE {ERR = FS.FAILF ("flag provided but not defined: -%s",  name)} }switch fs.errorhandling {case continueonerror:return errcase exitonerror:os.exit (2) Case paniconerror:panic (err)}}return nil}

From the Prase function, the key step of the implementation is the so-called Praseone function, look at this function together

func  (Fs *flagset)  parseone ()   (bool, string, error)  {if len (Fs.args)  == 0 {return false,  "",  nil}//note the type arguments []string,string array of our arguments, s means the first parameter s := fs.args[0]//such as the docker attach  command followed by the argument is containerid,s[0]!= '-', return to//do not matter, back to the parse, Then return nil, so this parameter does not require too many check and assignment Flagset additional operations If len (s)  == 0 | |  s[0] !=  '-'  | |  len (s)  == 1 {return false,  ", nil}if s[1] ==  '-'   && len (s)  == 2 { //  "--"  terminates the flagsfs.args  = fs.args[1:]return false,  "",  nil}//the first parameter out of '-' assignment to Namename := s[1:]if  len (name)  == 0 | |  name[0] ==  ' = '  {return false,  ' ",  fs.failf (" Bad flag syntax:  %s ",  s)}//refers to the next parameter fs.args = fs.args[1:]hasvalue := falsevalue := " "Find the location of "=", separating the string if i := strings. Index (name,  "=");  i != -1 {value = trimquotes (name[i+1:])  //"=" The back is valuehasvalue = truename = name[:i] //  "="   Front is name}         //like args = --log-driver=json-file  name = -. Log-driver value =json-filem := fs.formalflag, alreadythere := m[name]  // map value, determine whether there//such as Attach command, Fs.formal exists name is Nostdin and Sig-proxy, the previous article has been mentioned if !alreadythere {if  name ==  "-help"  | |  name ==  "Help"  | |  name ==  "H"  { // special case for nice help  Message.fs.usage () return false,  "",  errhelp}if len (name)  > 0 &&  name[0] ==  '-'  {return false,  ' ",  fs.failf (" Flag provided but  not defined: -%s ",  name)}return false, name, errretry}//bool The set value of the type, HasValue is the IF&NBSP;FV to be judged before looking for" = "  ok := flag. Value. (Boolflag);  ok && fv. Isboolflag ()  { // special case: doesn ' T need an argif hasvalue  {        //here sets the value of flag IF&NBSP;ERR&NBSP;:=&NBSP;FV. Set (value); err != nil {return false,  "",  fs.failf ("Invalid boolean  value %q for  -%s: %v ",  value, name, err)}}&NBSP;ELSE&NBSP;{FV. Set ("true")}} else {// it must have a value, which might be  the next argument.if !hasvalue && len (Fs.args)  > 0 {/ / value is the next arg //did not find "="  value on the next parameter hasvalue =  Truevalue, fs.args = fs.args[0], fs.args[1:]}if !hasvalue {return false,  "",  fs.failf ("flag needs an argument: -%s",  Name)}//sets the value of the non-bool flag if err := flag. Value.set (value); err != nil {return false,  "",  fs.failf ("invalid  Value %q for flag -%s: %v ",  value, name, err)}}if fs.actual  == nil {fs.actual = make (Map[string]*flag)}fs.actual[name] = flag // The current value is assigned to fs.actual //the following is the name of the command that may be modified later, the For i, n := range flag of the handyman. Names {if n == fmt. Sprintf ("#%s",  name)  {replacement :=  "" for j := i; j <  Len (flag. Names);  j++ {if flag. names[j][0] !=  ' # '  {replacement = flag. names[j]break}}if replacement !=  ""  {                   &nbsP;         fmt. fprintf (fs. Out (),  "warning:  '-%s '  is deprecated, it will be replaced                                   by  '-%s '  soon.  See usage.\n ",  name, replacement)} else {fmt. fprintf (fs. Out (),  "warning:  '-%s '  is deprecated, it will be remo                                  ved soon. see usage.\n " ,  name)}}}return true,  "",  nil}

Do you remember what was missing from the middle? Of course, how does the set of flags come true?

The value of flag is inherently an interface interface, which implements the String and set methods of the interface, implements the assignment of the interface type and variable type value interface {string () Stringset (String) error}//--bool Valuetype boolvalue Boolfunc Newboolvalue (val bool, p *bool) *boolvalue {*p = Valreturn (*boolvalue) (p)}/ /through Golang object-oriented interface implementation, set method, the interface of different types of value unified, implementation can extend the Func (b *boolvalue) Set (s string) error {V, err: = StrConv. Parsebool (s) *b = Boolvalue (v) return Err}func (b *boolvalue) Get () interface{} {return bool (*B)}func (b *boolvalue) Strin G () string {return FMT. Sprintf ("%v", *b)}func (b *boolvalue) Isboolflag () bool {return true}

For this reason, Fs.actual[name] has assigned the value of the flag type, the setting of the parameter value of the command line is over, and the next time we continue to share the interaction between Docker CLI and Docker daemon


How the Docker CLI interprets the parameters

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.