Tarkibga o'tish

Buyruq qatori dasturlari va standart oqimlar

Buyruq qatori interfeysi (CLI) terminaldan argument qabul qilib, natijani yana terminalga chiqaradigan dasturdir. Go’ning os va flag paketlari kichik CLI dasturlarini tashqi kutubxonasiz yozishga yordam beradi.

os.Args bilan argument olish

os.Args — dasturga berilgan argumentlarni saqlovchi []string. Birinchi element har doim ishga tushirilgan dastur nomi yoki yo‘li bo‘ladi:

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println("Dastur:", os.Args[0])
    fmt.Println("Argumentlar:", os.Args[1:])
}
go run main.go olma anor

go run ishlatilganda os.Args[0] vaqtinchalik bajariladigan fayl yo‘li bo‘lishi mumkin. Shu sabab dastur mantig‘ini aniq fayl nomiga bog‘lamang. os.Args[1:] esa foydalanuvchi bergan argumentlarni qaytaradi.

flag paketi

flag nomlangan parametrlarni e’lon qilish, tekshirish va yordam matnini chiqarishni soddalashtiradi:

name := flag.String("name", "mehmon", "foydalanuvchi nomi")
count := flag.Int("count", 1, "takrorlash soni")
quiet := flag.Bool("quiet", false, "natijani chiqarmaslik")
flag.Parse()

String, Int va Bool funksiyalari qiymatga ko‘rsatkich qaytaradi. flag.Parse() argumentlarni tahlil qilgandan keyin *name, *count va *quiet orqali qiymat olinadi. flag.Args() esa flaglardan keyin qolgan pozitsion argumentlarni beradi.

Standart oqimlar

Jarayonda uchta standart oqim mavjud:

  • os.Stdin — kirish ma’lumoti;
  • os.Stdout — odatiy natija;
  • os.Stderr — xato va diagnostika xabarlari.

Oddiy natijani stdout’ga, xatoni stderr’ga yozish shell orqali ularni alohida yo‘naltirish imkonini beradi:

fmt.Fprintln(os.Stdout, "Natija tayyor")
fmt.Fprintln(os.Stderr, "Xato: qiymat noto‘g‘ri")

fmt.Println() odatda stdout’ga yozadi. Terminaldan matn o‘qish uchun fmt.Fscan(os.Stdin, &value) yoki bufio.NewScanner(os.Stdin) ishlatilishi mumkin.

Exit code

Dastur muvaffaqiyatli tugasa, odatda 0 exit code qaytaradi. Nol bo‘lmagan qiymat xatoni bildiradi. os.Exit(code) jarayonni darhol to‘xtatadi.

Warning

os.Exit() chaqirilganda defer bilan rejalashtirilgan funksiyalar bajarilmaydi. Tozalash ishlarini run() kabi alohida funksiyada bajaring, os.Exit()ni esa main()da yakuniy natija uchun chaqiring.

Ishlaydigan CLI misoli

main.go
package main

import (
    "errors"
    "flag"
    "fmt"
    "io"
    "os"
)

func run(args []string, stdout, stderr io.Writer) int {
    fs := flag.NewFlagSet("salom", flag.ContinueOnError)
    fs.SetOutput(stderr)
    name := fs.String("name", "", "salomlashiladigan ism")
    count := fs.Int("count", 1, "takrorlash soni")
    quiet := fs.Bool("quiet", false, "natijani chiqarmaslik")

    if err := fs.Parse(args); err != nil {
        return 2
    }
    if *name == "" {
        fmt.Fprintln(stderr, errors.New("-name parametri kerak"))
        return 1
    }
    if *count < 1 {
        fmt.Fprintln(stderr, "xato: -count musbat bo‘lishi kerak")
        return 1
    }
    if *quiet {
        return 0
    }
    for i := 0; i < *count; i++ {
        fmt.Fprintf(stdout, "Salom, %s!\n", *name)
    }
    return 0
}

func main() {
    os.Exit(run(os.Args[1:], os.Stdout, os.Stderr))
}
go run main.go -name Dilshod -count 2

run() argumentlar va oqimlarni parametr sifatida olgani uchun uni test qilish oson. Flag sintaksisi xatosi uchun 2, noto‘g‘ri qiymat uchun 1, muvaffaqiyat uchun 0 qaytarildi.

Xulosa

os.Args barcha argumentlarni beradi, flag esa nomlangan parametrlarni tahlil qiladi. Natija va xatoni tegishlicha stdout hamda stderr’ga yozing. os.Exit()ni defer ishlaydigan funksiyalardan tashqarida, jarayonning yakuniy chegarasida chaqiring.