美文网首页
go包:os系统

go包:os系统

作者: 呦丶耍脾气 | 来源:发表于2023-03-30 19:40 被阅读0次

    1.介绍

    os包中提供了操作系统函数的接口,是一个比较重要的包。它的作用主要是在服务器上进行系统的基本操作,如文件操作、目录操作、执行命令、信号与中断、进程、系统状态等等。下面分模块归纳一些常用函数。

    2. 系统信息

    2.1 函数列表

    函数 功能
    Hostname() 获取当前主机名
    Getpid() 返回调用者所在进程的进程ID
    Getppid() 返回调用者所在进程的父进程的进程ID
    Exit() 让程序以状态码code退出。状态码0表示成功,非0表示出错。
    code取值范围: [0,125]

    2.2 代码示例

    a. 示例一

    // 系统相关
    func TestSystemInfo(t *testing.T) {
        hostname, _ := os.Hostname()
        // 主机名: huideMacBook-Pro.local
        fmt.Printf("主机名:%v \n", hostname)
        // 调用者所在进程的进程ID: 42862
        fmt.Printf("调用者所在进程的进程ID: %v \n", os.Getpid())
        // 调用者所在进程的进程的父进程ID: 42861 
        fmt.Printf("调用者所在进程的进程的父进程ID: %v \n", os.Getppid())
    }
    

    b. 示例二

    func TestExit(t *testing.T) {
        fmt.Println("调用前打印...")
        // 调用退出程序:code范围应在 0 <= x <= 125
        os.Exit(0)
        // 后面代码不会执行
        fmt.Println("调用后,这里不会输出")
    }
    /** 输出
    === RUN   TestExit
    调用前打印...
    
    Process finished with exit code 0
    */
    

    3.环境变量

    3.1 函数列表

    函数 功能
    Environ() 获取所有环境变量
    Setenv(key, value string) 设置环境变量
    Getenv(key string) 获取环境变量
    Clearenv() 清空所有环境变量

    3.2 代码示例

    // 环境变量相关
    func TestEnv(t *testing.T) {
        // 所有环境变量
        fmt.Printf("所有环境变量:%+v \n", os.Environ())
        // 设置环境变量
        _ = os.Setenv("my-name", "张三")
        // 获取环境变量
        fmt.Printf("获取环境变量: %v \n", os.Getenv("my-name"))
        // 清空所有环境变量
        os.Clearenv()
        fmt.Printf("清空环境变量后:%+v \n", os.Environ())
    }
    

    **输出: **

    === RUN   TestEnv
    所有环境变量:[PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin __CFBundleIdentifier=com.jetbrains.goland SHELL=/bin/zsh SECURITYSESSIONID=186a6 GOPATH=/Users/hui/go TERM=xterm-256color USER=hui GOROOT=/usr/local/go TMPDIR=/var/folders/8f/vnx2y1h57nzbd2p4vtcl6hv80000gn/T/ LaunchInstanceID=D9F74359-45B7-45F3-B74C-67CEA4DB8D9D COMMAND_MODE=unix2003 GO111MODULE=on SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.5K5WgUh7Hh/Listeners GOPROXY=https://goproxy.cn,direct XPC_FLAGS=0x0 __CF_USER_TEXT_ENCODING=0x1F5:0x19:0x34 LOGNAME=hui XPC_SERVICE_NAME=application.com.jetbrains.goland.15834002.15834933 PWD=/Users/hui/Project/Go/gin-learn/test HOME=/Users/hui GOARCH=amd64 GOBIN=/Users/hui/Project/Go/gopath/bin GOCACHE=/Users/hui/Library/Caches/go-build GOENV=/Users/hui/Library/Application Support/go/env GOHOSTARCH=amd64 GOHOSTOS=darwin GOMODCACHE=/Users/hui/go/pkg/mod GOOS=darwin GOSUMDB=sum.golang.org GOTOOLDIR=/usr/local/go/pkg/tool/darwin_amd64 GCCGO=gccgo AR=ar CC=clang CXX=clang++ CGO_ENABLED=1] 
    获取环境变量: 张三 
    清空环境变量后:[] 
    --- PASS: TestEnv (0.00s)
    PASS
    

    4.文件相关

    关于文件相关的函数,参见之前的文章 Go学习(二十四):文件操作

    5.进程相关

    5.1 方法列表

    函数名 功能
    os.StartProcess(..) (*Process, error) 根据提供的参数创建一个新进程
    p.Signal(sig Signal) 向进程发送一个信号
    p.Wait() 阻塞到进程退出,返回类型*os.ProcessState
    ps.Pid() 返回一个已退出进程的id
    ps.Exited() 报告进程是否已退出
    ps.Success() 报告进程是否成功退出,在Unix中状态码0代表退出。
    ps.SystemTime() 退出进程及子进程耗费的系统CPU时间
    ps.UserTime() 退出进程及子进程耗费的用户CPU时间
    ps.String() 退出进程的状态信息

    上表中p代表: *os.Process, ps代表: *os.ProcessState

    5.2 代码示例

    func TestCreateProcess(t *testing.T) {
        // 创建一个新进程执行; ls /
        args := []string{"/"}
        process, err := os.StartProcess("/bin/ls", args, &os.ProcAttr{})//win下创建方式还没找到
        if err != nil {
            t.Error("创建新进程失败: " + err.Error())
            return
        }
        fmt.Printf("当前新线程信息: %+v \n", process)
    
        // 2秒后向进程发送信号
        time.AfterFunc(2 * time.Second, func() {
            fmt.Println("发送进程退出信号...")
            _ = process.Signal(os.Kill)
        })
        // 手动阻塞看是否执行:发送信号
        time.Sleep(3 * time.Second)
    
        // 等待进程退出,返回ProcessState类型
        processState, _ := process.Wait()
        // 返回一个已退出进程的id
        fmt.Printf("当前进程Id: %v \n", processState.Pid())
        // 报告进程是否已退出
        fmt.Printf("进程是否已退出: %v \n", processState.Exited())
        // 报告进程是否成功退出,如在Unix里以状态码0退出。
        fmt.Printf("进程是否成功退出: %v \n", processState.Success())
        // 返回已退出进程及其子进程耗费的系统CPU时间。
        fmt.Printf("进程及子进程耗费系统CPU时间: %v \n", processState.SystemTime())
        // 返回已退出进程及其子进程耗费的用户CPU时间。
        fmt.Printf("进程及子进程耗费用户CPU时间: %v \n", processState.UserTime())
        fmt.Printf("进程状态: %s \n",processState.String())
    }
    

    输出:

    === RUN   TestCreateProcess
    当前新线程信息: &{Pid:46859 handle:0 isdone:0 sigMu:{w:{state:0 sema:0} writerSem:0 readerSem:0 readerCount:0 readerWait:0}} 
    当前进程Id: 46859 
    进程是否已退出: true 
    进程是否成功退出: true 
    进程及子进程耗费系统CPU时间: 1.563ms 
    进程及子进程耗费用户CPU时间: 503µs 
    发送进程退出信号...
    进程状态: exit status 0 
    --- PASS: TestCreateProcess (3.00s)
    PASS
    

    6. 执行命令

    os/exec包执行外部命令。它包装了os.StartProcess函数以便更容易的修正输入和输出,使用管道连接I/O,以及其它的一些优化。

    6.1 方法列表

    方法 功能
    LookPath(file string) (string, error) 在环境变量PATH中搜索可执行文件
    (c *Cmd) Run() error 执行c包含的命令,并阻塞直到完成
    (c *Cmd) Start() error 执行c包含的命令即刻返回,但不会等待该命令完成。
    (c *Cmd) Wait() error 会阻塞直到该命令执行完成,和Start()结合使用
    (c *Cmd) Output() ([]byte, error) 执行命令并返回标准输出的切片
    (c *Cmd) CombinedOutput() ([]byte, error) 执行命令并返回标准输出和错误输出合并的切片。

    6.2 使用示例

    1. LookPath
    // 在环境变量PATH中搜索可执行文件
    func TestLookPath(t *testing.T) {
        path, err := exec.LookPath("go")
        if err != nil {
            t.Error(err)
        }
        fmt.Println(path)
    }
    /** 输出
    === RUN   TestLookPath
    /usr/local/go/bin/go
    --- PASS: TestLookPath (0.00s)
    PASS
    */
    
    2.Run
    // 使用Run()执行命令
    func TestRun(t *testing.T) {
        // 执行: go version
        cmd := exec.Command("sleep", "3s")
        // 具体执行
        err := cmd.Run()
        if err != nil {
            t.Errorf("执行失败:%v\n",err)
        }
        fmt.Printf("cmd.Path: %v \n",cmd.Path)
        fmt.Printf("cmd.Args: %v \n",cmd.Args)
    }
    /** 输出
    === RUN   TestRun
    cmd.Path: /bin/sleep 
    cmd.Args: [sleep 3s] 
    --- PASS: TestRun (3.01s)
    PASS
    */
    
    3. Start
    // 使用Start执行命令
    func TestStart(t *testing.T) {
        // 执行: go version
        cmd := exec.Command("sleep", "3s")
        // Start开始执行c包含的命令,但并不会等待该命令完成即返回
        err := cmd.Start()
        if err != nil {
            t.Errorf("执行失败:%v\n",err)
        }
        //Wait会阻塞直到该命令执行完成
        err = cmd.Wait()
        fmt.Printf("执行完成: %v \n",err)
        fmt.Printf("cmd.Path: %v \n",cmd.Path)
        fmt.Printf("cmd.Args: %v \n",cmd.Args)
    }
    
    /** 输出
    === RUN   TestStart
    执行完成: <nil> 
    cmd.Path: /bin/sleep 
    cmd.Args: [sleep 3s] 
    --- PASS: TestStart (3.00s)
    PASS
    */
    
    4.Output
    // 执行命令并获取输出结果
    func TestOutput(t *testing.T) {
        // 执行: go version
        output, _ := exec.Command("go", "version").Output()
        fmt.Printf("结果: %s \n",output)
        // 执行: du -sh .
        output2, _ := exec.Command("du", "-sh",".").Output()
        fmt.Printf("结果: %s \n",output2)
    }
    
    /** 输出
    === RUN   TestOutput
    结果: go version go1.15.5 darwin/amd64
    
    结果:  36K    .
    
    --- PASS: TestOutput (0.02s)
    PASS
    */
    
    5.CombinedOutput
    // 执行命令并返回标准输出和错误输出合并的切片
    func TestCombinedOutput(t *testing.T) {
        // 执行: go version-1 故意写错
        output, _ := exec.Command("go", "version-1").CombinedOutput()
        fmt.Printf("结果: %s \n",output)
    }
    
    /** 输出
    === RUN   TestCombinedOutput
    结果: go version-1: unknown command
    Run 'go help' for usage.
    
    --- PASS: TestCombinedOutput (0.01s)
    PASS
    */
    

    相关文章

      网友评论

          本文标题:go包:os系统

          本文链接:https://www.haomeiwen.com/subject/bbsnrdtx.html