தொகுதி பாடங்கள் (4/5)
சிறு திட்டம்: கொடிகள் கொண்ட ஒரு CLI
flag தொகுப்பைக் கொண்டு கொடி பாகுபடுத்துதல், os.Stderr இல் பிழைகள், மற்றும் சரியான வெளியேறும் குறியீடு ஆகியவற்றைக் கொண்டு ஒரு சிறிய idiomatic CLI ஐ உருவாக்க முந்தைய தொகுதிகளின் கட்டுமானத் தொகுதிகளை ஒன்றாக இணைப்போம்.
flag தொகுப்பு
package main
import (
"flag"
"fmt"
"os"
)
func main() {
n := flag.Int("n", 1, "number of repetitions")
upper := flag.Bool("u", false, "print in uppercase")
flag.Parse()
args := flag.Args() // remaining positional arguments
if len(args) < 1 {
fmt.Fprintln(os.Stderr, "usage: echo [-n N] [-u] <text>")
os.Exit(2)
}
text := args[0]
if *upper {
text = strings.ToUpper(text)
}
for i := 0; i < *n; i++ {
fmt.Println(text)
}
}முக்கிய புள்ளிகள்:
flag.Int,flag.String,flag.Bool,flag.Duration(முதலியன.) சுட்டி: நீங்கள்*n, AGYTOK_8INLINE_INLINE__ஐப் பயன்படுத்துகிறீர்கள்.flag.Parse()மதிப்புகளைப் படிக்கும் முன் மற்றும்flag.Args()க்கு முன் ஒருமுறை அழைக்கப்பட வேண்டும்.flag.Args()நிலை தருமதிப்புகளை (--க்குப் பின் அல்லது கடைசிக் கொடிக்குப் பின்) வழங்கும்.- ஏற்றுக்கொள்ளப்பட்ட படிவங்கள்:
-n 3,-n=3,--n=3. பூலியன்கள்:-u(உண்மை),-u=false.
வழக்கமான வெளியேறும் குறியீடுகள்
os.Exit(0) // success
os.Exit(1) // generic error
os.Exit(2) // usage error (incorrect flag usage)ஷெல்களும் ஸ்கிரிப்ட்களும் இந்தக் குறியீடுகளை எதிர்பார்க்கின்றன: அவற்றைத் தொடர்ந்து பயன்படுத்தவும். ஒருபோதும் os.Exit உடன் முக்கிய அல்லாத கோரூட்டினிலிருந்து வெளியேறவும்: இது log ஃப்ளஷிங் உட்பட ஒவ்வொரு defer ஐயும் தவிர்க்கிறது.
Stderr vs Stdout
பழைய மற்றும் புனிதமான யூனிக்ஸ் விதி:
os.Stdout→ பயனுள்ள வெளியீடு, குழாய் திறன் (cli | grep ...).os.Stderr→ கண்டறிதல், பிழைகள், முன்னேற்றப் பட்டைகள், பயன்பாடு.
fmt.Println("result: 42") // stdout
fmt.Fprintln(os.Stderr, "error: ...") // stderrஇந்த வழியில் cli 2>/dev/null முடிவுகளை மட்டுமே காட்டுகிறது, cli >out.txt முடிவை மட்டும் திசைதிருப்புகிறது மற்றும் பிழைகள் தெரியும்.
log எதிராக fmt
fmtபயனர் வெளியீட்டிற்கு.logநோயறிதலுக்காக: நேர முத்திரையைச் சேர்க்கிறது, இயல்பாகos.Stderrக்கு எழுதுகிறது,log.Fatal(பதிவுகள் +os.Exit(1)) மற்றும் AGYTOK_34INLINE_LINE_34.
log.SetFlags(log.LstdFlags | log.Lshortfile) // timestamp + file:line
log.Fatal("boom") // prints and exits with 1நவீன பயன்பாடுகளுக்கு (Go 1.21+) log/slog கட்டமைக்கப்பட்ட பதிவுகளுக்கு (JSON அல்லது உரை, நிலைகள், தட்டச்சு செய்த புலங்கள்) பயன்படுத்தவும்.
கட்டிடக்கலை: லாஜிக்கிலிருந்து main பிரிக்கவும்
func main() {
if err := run(os.Args[1:], os.Stdout, os.Stderr); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func run(args []string, stdout, stderr io.Writer) error {
// here use a new flag.FlagSet instead of the global flag.CommandLine
fs := flag.NewFlagSet("echo", flag.ContinueOnError)
fs.SetOutput(stderr)
n := fs.Int("n", 1, "repetitions")
if err := fs.Parse(args); err != nil {
return err
}
// ...
return nil
}நன்மைகள்:
- சோதனை: நீங்கள்
bytes.Bufferஐ stdout/stderr ஆக கடந்து, வெளியீட்டைச் சரிபார்க்கவும். - உலகளாவிய நிலை இல்லை: ஒவ்வொரு
FlagSetதனிமைப்படுத்தப்பட்டுள்ளது. mainசிறியதாக இருக்கும்: இது IO + பிரதிநிதிகளைத் தயார்படுத்துகிறது.
துணைக் கட்டளைகள்
துணைக் கட்டளைகளைக் கொண்ட CLIகளுக்கு (mycli serve, mycli migrate), வெளிப்புற சார்புகள் இல்லாத திட்டம்:
func main() {
if len(os.Args) < 2 {
usage()
os.Exit(2)
}
switch os.Args[1] {
case "serve":
serveCmd(os.Args[2:])
case "migrate":
migrateCmd(os.Args[2:])
default:
usage()
os.Exit(2)
}
}ஒவ்வொரு துணைக் கட்டளைக்கும் அதன் சொந்த flag.NewFlagSet உள்ளது. பெரிய திட்டங்களுக்கு, cobra அல்லது urfave/cli போன்ற நூலகங்கள் தானாக உருவாக்கப்பட்ட உதவியுடன் இந்தத் திட்டத்தை வடிவமைக்கின்றன.
பயிற்சிகள்
Definisci il flag -n di tipo int con valore di default 1 e descrizione 'ripetizioni', poi chiama flag.Parse() e Stampa il valore.
3 முயற்சிகளுக்குப் பிறகு தீர்வு கிடைக்கும்
Se non c'è almeno un argomento posizionale dopo flag. Parse, Stampa 'manca argomento' su Stderr e termina con os.Exit(1).
3 முயற்சிகளுக்குப் பிறகு தீர்வு கிடைக்கும்
ஒரு CLI யூனிக்ஸ்-நட்பு இல் க்வாலே ஸ்ட்ரீம் ஸ்டாம்பி மெசக்கி டி பிழை மற்றும் பயன்பாடு?
fmt.Fprintln(???, "uso: prog ...")