01-Linux创建用户

1: userdel删除用户

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 若使用userdel haha 命令删除该用户时,并不能删除该用户的所有信息,
# 只是删除了/etc/passwd、/etc/shadow、/etc/group/、/etc/gshadow四个文件里的该账户和组的信息

  [root@localhost /]# userdel haha
  [root@localhost /]# cat /etc/passwd | grep haha
  [root@localhost /]# cat /etc/shadow | grep haha
  [root@localhost /]# cat /etc/group | grep haha
  [root@localhost /]# cat /etc/gshadow | grep haha
  [root@localhost /]# find / -name "*haha*"

# 完全删除用户,慎用!!!
userdel -r haha

2: useradd创建用户

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 1 在home手动创建新用户home目录
useradd -d /home/haha haha

# 2 设置密码
passwd haha

# 3 设置sudo权限
(1)su root //进入root用户
(2)vim /etc/sudoers //打开sudo的配置文件
    修改sudoers文件:
    <1> 先找到所示的一行:(root ALL=(ALL)ALL)
    <2> 然后给普通用户haha添加sudo权限,在“root ALL=(ALL)ALL”这一行下面,加入如下图所示的一行(用户名 ALL=(ALL) ALL),并保存

3: 新用户使用ssh登录验证

02-Go编译相关

1: go 交叉编译

1.1 查看可支 platform

1
2
3
go tool dist list

// 支持的OS跟ARCH

1.2 Go 交叉编译命令

1
2
3
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -a -o vp-server_linux_amd64
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build

1.3 编译命令

1.4 编译时传入参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var (
	VERSION    string
	BUILD_TIME string
	GO_VERSION string
)

func main() {
	fmt.Printf("%s\n%s\n%s\n", VERSION, BUILD_TIME, GO_VERSION)
}

// go build -ldflags "-X main.VERSION=1.0.0 -X 'main.BUILD_TIME=`date +"%Y-%m-%d %H:%M:%S"`' -X 'main.GO_VERSION=`go version`'"
 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
# go
var (
	VERSION     string
	BUILD_TIME  string
	GO_VERSION  string
	COMMIT_ID   string
	AUTHOR      string
	BRANCH_NAME string
)

func init() {
	log.Infof("\nVERSION:%s \nBUILD_TIME:%s \nGO_VERSION:%s \nCOMMIT_ID:%s \nAUTHOR:%s \nBRANCH_NAME:%s\n",
		VERSION, BUILD_TIME, GO_VERSION, COMMIT_ID, AUTHOR, BRANCH_NAME)
}
# go build shell

#!/bin/sh

VERSION="v1.0.0"
BUILD_TIME=`date +"%Y-%m-%d %H:%M:%S"`
GO_VERSION=`go version`
COMMIT_ID=`git log |head -n 1| awk '{print $2;}'`
AUTHOR=`git log |head -n 3| grep Author| awk '{print $2;}'`
BRANCH_NAME=`git branch | awk '/\*/ { print $2; }'`

go build -ldflags \
"-X 'main.VERSION=${VERSION}' \
-X 'main.BUILD_TIME=${BUILD_TIME}' \
-X 'main.GO_VERSION=${GO_VERSION}' \
-X 'main.COMMIT_ID=${COMMIT_ID}' \
-X 'main.AUTHOR=${AUTHOR}' \
-X 'main.BRANCH_NAME=${BRANCH_NAME}' "

2: shell 脚本

 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
#!/bin/bash
export LANG="en_US.UTF-8"

echo "开始编译vp-server项目... "
echo "----> 1: linux (64) ; "
echo "----> 2: windows (64) ; "
echo "----> 3: darwin (64) ; "

if read -p "======>请选择您要编译的环境 :" args
then
    echo "------> 你输入的环境是 $args <------"
else
    echo "\n抱歉,你输入超时了。"
fi

echo
projectName="video_server"

if [ $args -eq 1 ]; then
  CGO_ENABLED=0 GOOS=linux GOARCH=amd64    go build -v -a -o ${projectName}_linux_amd64
elif [ $args -eq 2 ]; then
  CGO_ENABLED=0 GOOS=windows GOARCH=amd64    go build -v -a -o ${projectName}_windows_amd64.exe
elif [ $args -eq 3 ]; then
  CGO_ENABLED=0 GOOS=darwin GOARCH=amd64    go build -v -a -o ${projectName}_darwin_amd64
else
    echo "输入的参数$args不正确,执行退出..."
    exit 1
fi
echo
echo "...build success!!! 编译成功..."

3: Makefile

 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
.PHONY: all build clean run check cover lint docker help
BIN_FILE=hello
all: check build
build:
	@go build -o "${BIN_FILE}"
clean:
	go clean
	rm --force "xx.out"
test:
	go test
check:
	go fmt ./
	go vet ./
cover:
	go test -coverprofile xx.out
	go tool cover -html=xx.out
run:
	./"${BIN_FILE}"
lint:
	golangci-lint run --enable-all
docker:
	@docker build -t leo/hello:latest .
help:
	@echo "make 格式化go代码 并编译生成二进制文件"
	@echo "make build 编译go代码生成二进制文件"
	@echo "make clean 清理中间目标文件"
	@echo "make test 执行测试case"
	@echo "make check 格式化go代码"
	@echo "make cover 检查测试覆盖率"
	@echo "make run 直接运行程序"
	@echo "make lint 执行代码检查"
	@echo "make docker 构建docker镜像"

03-Git常见的命令集合

01-docker清理

Docker 清理常用方法

Docker 基于 Linux 内核通过操作系统和虚拟容器调用 CGroup, Namespace 等系统接口完成资源的分配与相互隔离,依赖系统资源运行,在分配回收过程中会产生一些垃圾,比如 docker stop 容器后没有执行 docker rm 删除。

01-Rust基本语法

rust 基本语法

1: 变量

 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
   fn f0(){
    println!("--------变量-----------");
    let a=12;
    let b =100;
    println!("a is {1},b is {0}",a,b);
    println!("{}","{}");
    println!("add(): {}",add(a, b));

    // 变量重新赋值
    let mut c=5;
    println!("c is  首次声明:{0}",c);
    c = 66;
    println!("c is  重新赋值:{0}",c);

    // 变量重新绑定,变量的值可以"重新绑定",但在"重新绑定"以前不能私自被改变
    // 重影(Shadowing)
    let a :i32=11;
    println!("a is重新绑定{}",a) ;


    // 常量
    const D: i32 = 99;
    println!("常量D:{0}",D);

    //
    let a:u64 =123;
    println!("a is重新绑定{}",a);

    // 重影(Shadowing)
    // 重影与可变变量的赋值不是一个概念,重影是指用同一个名字重新代表另一个
    // 变量实体,其类型、可变属性和值都可以变化。但可变变量赋值仅能发生值的变化。
    let x =5;
    let x=x+1;
    let x=x*2;
    println!("the value of x is:{}",x);
}

// rust 不支持自动返回值类型判断
// 如果没有明确函数返回值类型,函数将被认为是"纯过程“,不允许产生返回值,return不能有返回值表达式
fn add(a:i32,b:i32)->i32{
    return a+b
}

2: float 类型

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
fn f1(){
    println!("--------float类型-----------");

    let x =2.0; //f64
    let y: f32 = 3.0;//f32

    println!("x is {0},y is {1}",x,y);

    let mut ok  =true;
    println!("ok is {}",ok);
    ok=false;
    println!("ok is {}",ok);
}

3: 复合类型:tuple 元组,arrary,slice

 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
fn f2(){
    println!("--------复合类型:tuple,array,slice-----------");
    // 复合类型
    // tuple元组 ,用一对()包括的一组数据,可以包含不同种类的数据
    let tup:(i32,f64,u8,char) = (10,9.9,5,'a');
    println!("元组 tup: {} {} {} {}",tup.0,tup.1,tup.2,tup.3);
    println!("元组 tup: {:?}",tup);
    println!("元组 tup: {:?}",tup.3);

    // 数组,用[]包含相同类型的数据
    let a = [1,2,3,4,5]; //a是一个长度为5的数组
    let b = ["go","rust","java"];//b是一个长度是4的字符串数组
    let c: [i32;5] = [1,2,3,4,5];//c是一个长度是5,类型是i32的数组

    println!("数组a 的a[0]元素 : {}",a[0]);
    println!("数组b 的元素: {:?}",b);
    println!("数组c 是长度是{}类型是{}的数组:{:?}",c.len(),"i32",c);

    // slice 切片是对数据值的部分引用
    // 1:字符串切片
    let s = String::from("broadcast");
    let part1 = &s[..5];
    let part2 =&s[5..];
    // 2:对象被部分引用,禁止更改值
    // s.push_str(",aod");//TODO 错误:s被部分引用,禁止修改其值
    println!("字符串切片:{}={}+{}",s,part1,part2);

    // 3:非字符串切片
    // let a=[1,2,3,4,5];
    let patr3 =&a[1..3];
    println!("{}",patr3[0]);
    println!("非字符串切片part3:{:?}",patr3);
}

4: 字符串

 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
    fn f3(){
    // rust中的字符串通常指 &str, String
    // rust内部的字符串默认是使用utf-8编码格式的(String和&str),
    // 而内置的char类型是4字节长度的,存储的是Unicode字符,所以Rust里面的字符串不能视为char类型的数组,而更接近u8类型的数组


    // 分的比较清.简单的可以理解为: &str 是分配在栈上, String分配在堆上.
    println!();
    println!();
    println!("--------str String  初始化 ...-----------");

    let mut a = String::from("food"); // 在堆上分配内存
    println!("as_ptr()打印堆内存的地址: {:p}", a.as_ptr()); // 打印堆内存的地址
    println!("&a 打印变量a 在栈上的地址: {:p}", &a); // 打印变量a 在栈上的地址
    println!("{} {}", a.len(),a.capacity()); // 字符串在堆内存中的字节长度, 不是字符长度!!!
    a.reserve(10); // 增加堆的内存长度
    println!("{} {}",a.len(), a.capacity()); // 总字节容量
    // 切片
    let e = &a[1..3];
    println!("切片 e: {:?},len是:{}",e,e.len());


    let str: String = String::new(); // 创建空字符串
    println!("str: {} , len: {}, cap: {}",str,str.len(),str.capacity());
    let str2: String = String::from("hello rust"); // 创建堆内存
    println!("str2: {}",str2);
    let str3: String = String::with_capacity(20); // 创建20字节的空堆内存
    println!("str3: {}, cap: {}",str3,str3.capacity());
    let str4: &'static str = "the tao of rust"; // 静态变量
    println!("str4: {}",str4);
    let str5: String = str4.chars().filter(|c| !c.is_whitespace()).collect(); // .chars() 返回 各字符
    println!("str5: {}",str5);
    let str6: String = str4.to_owned(); // 与 to_string() 基本相同
    println!("str6: {}",str6);
    let str7: String = str4.to_string();
    println!("str7: {}",str7);
    let str: &str = &str4[11..15]; // 取静态字符串的部分内容, 学名 切片 (slice)
    println!("str: {}",str);


    println!("--------字符串增加 ...-----------");
    let mut hello = String::from("hello,");
    hello.push('R');
    hello.push_str("-Rust");
    hello.insert_str(2,"-");
    println!("hello字符串增加1: {}",hello);
    let suffix =String::from("-rust");
    hello=hello+&suffix; //NOTE: +后面的对象要带&
    println!("hello字符串增加2: {}",hello);


    println!("--------字符串遍历 ...-----------");
    let s = String::from("good evening...");
    let s: String = s.chars().enumerate().map(|(i,c)|{
        if i%2 == 0{
            c.to_lowercase().to_string()
        }else{
            c.to_uppercase().to_string()
        }
    }).collect();
    println!("s遍历: {}",s);


    println!("--------字符串位置查询以及子串...-----------");
}

5: 条件分支

 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
fn f4(){
    println!("--------条件判断语句...-----------");
    // if
    let a = 12;
    let b;
    if a>0{
        b=1;
    }else if a<0{
        b=-1;
    }else{
        b=0;
    }

    println!("b is {}",b);


    // 三元条件表达式 (A?B:C)
    let a=3;
    let number=if a > 0 {1} else {-1};
    println!("number is {}",number);

    // match  多条件分支
    // TODO match 除了能够对enum类型进行分支选择以外,还可以对整数、浮点数、字符和字符串切片引用(&str)类型的数据进行分支选择。
    // TODO 其中,浮点数类型被分支选择虽然合法,但不推荐这样使用,因为精度问题可能会导致分支错误。
    let n ="abc";
    match n{
        "abc"=>println!("Yes"),
        _=>{},
    }

    // TODO: if let语句
    /*
    if let 匹配值 = 源变量 {
        语句块
    }else{

    }
    */
    enum Book{
        Papery(u32),
        Electronic(String)
    }
    let book=Book::Electronic(String::from("url"));
    if let Book::Papery(index)=book{
            println!("Papery:{}",index);
    }else{
            println!("not papery book");
    }
}

6: 循环语句

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
fn f5(){
    println!("--------循环语句...-----------");
    let mut i: i32;
    i=0;
    while i<4{
        println!("i:{}",i);
        i=i+1;
    }

    let arr=[10,20,30,40,50];
    for i in arr.iter(){ //迭代器 iter(),iter_num()
        println!("for in iter() 遍历: {}",i);
    }

    for i in 0..arr.len(){
        println!("for in 下标 遍历: {}",i);
    }
}

7: 所有权 ownership

// rust 所有权 // 1: Rust 中的每一个值都有一个变量,称其为所有者; // 2:一次只能有一个所有者; // 3:当所有者不在程序的运行范围时,该值将被删除。

01-win10安装Rust步骤

1: 首先配置环境变量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 修改为国内镜像
#    由于rustup的官方服务器在国外,如果直接按照rust官网的方式安装,
#    非常慢且容易fail
RUSTUP_DIST_SERVER=http://mirrors.ustc.edu.cn/rust-static
RUSTUP_UPDATE_ROOT=http://mirrors.ustc.edu.cn/rust-static/rustup


# rust 安装路径
CARGO_HOME:D:\Program Files\RUST\.cargo
RUSTUP_HOME:D:\Program Files\RUST\.rustup

#
~/.cargo/bin 添加到PATH

# 下载安装racer (rust代码补全程序)
# 如果不成功,先将rustup更新成nightly版本,再进行下载:
rustup install nightly
cargo +nightly install racer

2:按照官网方式进行安装

地址:https://www.rust-lang.org/zh-CN/tools/install