forked from ffhelicopter/Go42
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path42_30_os.md
133 lines (102 loc) · 4.96 KB
/
42_30_os.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# 《Go语言四十二章经》第三十章 os包
作者:李骁
## 30.1 启动外部命令和程序
os标准包,是一个比较重要的包,顾名思义,主要是在服务器上进行系统的基本操作,如文件操作,目录操作,执行命令,信号与中断,进程,系统状态等等。在os包下,有
exec,signal,user三个子包。
在os包中,有很多有趣的功能,比如可以通过变量Args来获取命令参数,os.Args返回一个字符串数组。
```Go
fmt.Println(os.Args)
```
在os包中,相关函数名字和作用有较重的UNIX风格,比如:
```
func Chdir(dir string) error //chdir将当前工作目录更改为dir目录
func Getwd() (dir string, err error) //获取当前目录
func Chmod(name string, mode FileMode) error //更改文件的权限
func Chown(name string, uid, gid int) error //更改文件拥有者owner
func Chtimes(name string, atime time.Time, mtime time.Time) error
func Clearenv() //清除所有环境变量(慎用)
func Environ() []string //返回所有环境变量
func Exit(code int) //系统退出,并返回code,其中0表示执行成功并退出,非0表示错误并退出
```
在os包中,有关文件的处理也有很多方法,如:
```
func Create(name string) (file *File, err error) // Create采用模式0666创建一个名为name的文件,如果文件已存在会截断它(为空文件)
func Open(name string) (file *File, err error) // Open打开一个文件用于读取。
func (f *File) Stat() (fi FileInfo, err error) // Stat返回描述文件f的FileInfo类型值
func (f *File) Readdir(n int) (fi []FileInfo, err error) // Readdir读取目录f的内容,返回一个有n个成员的[]FileInfo
func (f *File) Read(b []byte) (n int, err error) // Read方法从f中读取最多len(b)字节数据并写入b
func (f *File) WriteString(s string) (ret int, err error) // 向文件中写入字符串
func (f *File) Sync() (err error) // Sync递交文件的当前内容进行稳定的存储。
func (f *File) Close() error // Close关闭文件f
```
有关文件的处理,将在下一章中详细说明。
在os 包中有一个 StartProcess 函数可以调用或启动外部系统命令和二进制可执行文件;它的第一个参数是要运行的进程,第二个参数用来传递选项或参数,第三个参数是含有系统环境基本信息的结构体。
这个函数返回被启动进程的 id(pid),或者启动失败返回错误。
```Go
package main
import (
"fmt"
"os"
)
func main() {
// os.StartProcess
env := os.Environ()
procAttr := &os.ProcAttr{
Env: env,
Files: []*os.File{
os.Stdin,
os.Stdout,
os.Stderr,
},
}
// example:
Pid, err := os.StartProcess("/bin/ls", []string{"ls", "-l"}, procAttr)
if err != nil {
fmt.Printf("Error %v starting process!", err) //
os.Exit(1)
}
fmt.Printf("The process id is %v", Pid)
}
```
## 30.2 os/signal 信号处理
一个运行良好的程序在退出(正常退出或者强制退出,如ctrl+c,kill等)时是可以执行一段清理代码,将收尾工作做完后再真正退出。一般采用系统Signal来通知系统退出,如kill pid。在程序中针对一些系统信号设置了处理函数,当收到信号后,会执行相关清理程序或通知各个子进程做自清理。
Go的系统信号处理主要涉及os包、os.signal包以及syscall包。其中最主要的函数是signal包中的Notify函数:
func Notify(c chan<- os.Signal, sig …os.Signal)
该函数会将进程收到的系统Signal转发给channel c。如果没有传入sig参数,那么Notify会将系统收到的所有信号转发给channel c。
Notify会根据传入的os.Signal,监听对应Signal信号,Notify()方法会将接收到对应os.Signal往一个channel c中发送。
下面代码以 syscall.SIGUSR2 信息为例,说明了具体实现:
```Go
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
go signalListen()
for {
time.Sleep(10 * time.Second)
}
}
func signalListen() {
c := make(chan os.Signal)
signal.Notify(c, syscall.SIGUSR2)
for {
s := <-c
//收到信号后的处理,这里只是输出信号内容,可以做一些更有意思的事
fmt.Println("get signal:", s)
}
}
```
关于信号有关信息,有兴趣建议可以参考《UNIX高级编程》。其他更多Signal信号类型,请参看相关手册。
os包中其他的功能还有很多,这里就不一一介绍了。
[目录](https://github.com/ffhelicopter/Go42/blob/master/SUMMARY.md)
[第二十九章 排序(sort)](https://github.com/ffhelicopter/Go42/blob/master/content/42_29_sort.md)
[第三十一章 文件操作与IO](https://github.com/ffhelicopter/Go42/blob/master/content/42_31_io.md)
>本书《Go语言四十二章经》内容在github上同步地址:https://github.com/ffhelicopter/Go42
>
>
>虽然本书中例子都经过实际运行,但难免出现错误和不足之处,烦请您指出;如有建议也欢迎交流。
>联系邮箱:[email protected]