基本信息

Centos 7 系统最小化安装,默认配置,是没有创建其他用户的。作为服务器操作系统,为了安全起见,一般是使用一般用户。这就牵涉到用户、用户组的创建以及删除。

此外,CentOS 7 和其他版本的Linux一样,都具有相应用户的配置文件及目录,如下:

1
2
3
4
5
6
7
/etc/passwd         //用户账户信息,可以看出用户名称 
/etc/shadow //用户账户加密后信息,包括但不限于/etc/passwd中的信息
/etc/group //组账户信息,可以看出组名称
/etc/gshadow     //组账户安全信息,包括但不限于/etc/group中的信息
/etc/default/useradd //账户创建时默认值
/etc/skel/ //包含默认文件的目录,具体作用尚不清楚
/etc/login.defs //安全性的默认配置,与上面/etc/default/useradd有区别

阅读更多

.DS_Store 文件

.DS_StoreFinder 用来存储这个文件夹的显示属性的:比如文件图标的摆放位置。

显示/隐藏 Mac 隐藏文件

  • 显示:defaults write com.apple.finder AppleShowAllFiles -bool true
  • 隐藏:defaults write com.apple.finder AppleShowAllFiles -bool false

阅读更多

当我们使用 Homebrew 安装软件时,由于一些特殊原因会出现软件包下载失败的情况。这种还很常见,我们没法改变环境,但却可以取巧的解决,那就是利用 Homebrew 缓存的特性,手动预先下载软件。

阅读更多

翻译Dockerfile: ENTRYPOINT vs CMD

在我们查阅Dockerfile的官方文档时, 有可能发现一些命令的功能重复(至少看起来干的事情差不多), 我已经在上文分析过ADD和COPY命令的区别(他们功能类似), 现在我们分析另外2个命令, 他们的功能也非常类似, 是CMD和ENTRYPOINT。尽管ENTRYPOINT和CMD都是在docker image里执行一条命令, 但是他们有一些微妙的区别。在绝大多数情况下, 你只要在这2者之间选择一个调用就可以. 但他们有更高级的应用, CMD和ENTRYPOINT组合起来使用, 完成更加丰富的功能

阅读更多

flag包概述

flag包实现了命令行参数的解析

flag包的工作流程

基本分为三步:

  • 注册flag,主要用flag.String(), Bool(), Int()等函数注册flag,或者用flag.BoolVar(),StringVar(),IntVar()等函数把flag绑定到变量
  • 解析flag,使用flag.Parse()函数解析在命令行使用了的flag
  • 最后根据命令行输入的flag处理逻辑

阅读更多

Compare

  • func Compare(a, b string) int

按照字典序比较两个字符串,通常情况下直接使用=,>,<会更快一些。

Contains,ContainsAny 和 ContainsRune

  • func Contains(s, substr string) bool
  • func ContainsAny(s, chars string) bool
  • func ContainsRune(s string, r rune) bool

阅读更多

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
package main

import (
"fmt"
"time"
)

type Bar struct {
percent int64 // 百分比
cur int64 // 当前进度位置
total int64 // 总进度
rate string // 进度条
graph string // 显示符号
}

func (bar *Bar) NewOption(start, total int64) {
bar.cur = start
bar.total = total
if bar.graph == "" {
bar.graph = "█"
}
bar.percent = bar.getPercent()
for i := 0; i < int(bar.percent); i += 2 {
bar.rate += bar.graph // 初始化进度条位置
}
}

func (bar *Bar) getPercent() int64 {
return int64(float32(bar.cur) / float32(bar.total) * 100)
}

func (bar *Bar) NewOptionWithGraph(start, total int64, graph string) {
bar.graph = graph
bar.NewOption(start, total)
}

func (bar *Bar) Play(cur int64) {
bar.cur = cur
last := bar.percent
bar.percent = bar.getPercent()
if bar.percent != last && bar.percent%2 == 0 {
bar.rate += bar.graph
}
fmt.Printf("\r[%-50s]%3d%% %8d/%d", bar.rate, bar.percent, bar.cur, bar.total)
}

func (bar *Bar) Finish() {
fmt.Println()
}

func main() {
var bar Bar
bar.NewOption(0, 100)
// bar.NewOptionWithGraph(0, 100, "#")
for i := 0; i <= 100; i++ {
time.Sleep(100 * time.Millisecond)
bar.Play(int64(i))
}
bar.Finish()
}

挂载配置文件到应用程序所在的目录

应用程序代码:

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
package main

import (
"fmt"
"io"
"io/ioutil"
"log"
"net/http"

"gopkg.in/yaml.v2"
)

type config struct {
Port string `yaml:"port"`
}

var c = new(config)

func init() {
fContent, err := ioutil.ReadFile("config.yaml")
if err != nil {
log.Fatal(err)
}

if err = yaml.Unmarshal(fContent, c); err != nil {
log.Fatal(err)
}
}

func main() {
handlerFunc := func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello !")
}

http.HandleFunc("/", handlerFunc)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", c.Port), nil))
}

阅读更多