移动周分享-第54期

自动化 ssh 授权笔记 - 曾铭

每次 ssh user@host 登录目标机器都要输密码是件很烦的事,特别是经常访问多台主机的情况。 最近写自动化脚本时碰到要自动做机器间 ssh 验证,碰到一些问题记录下来备忘。

分析

  • 通过 ssh-keygen -t rsa -b 4096 -C "your_email@example.com" 命令生成本地机器的私钥和公钥: ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub
  • 授权就是将将本地机器的公钥加入到目标机器的 ~/.ssh/authorized_keys 中供验证用
  • 本地 ~/.ssh/known_hosts 中信任目标机器的公钥指纹

自动做 ssh-key 授权

1
2
3
4
# copy local ssh-key to remote 对应分析中的第二步
cat ~/.ssh/id_rsa.pub | ssh root@192.168.37.110 "cat >> ~/.ssh/authorized_keys"
# add host to known_hosts 对应分析中的第三步
ssh-keyscan -t rsa "192.168.37.110" >> ~/.ssh/known_hosts

或者这两条命令可以精简为如下一条

1
2
brew install ssh-copy-id # just for mac
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.37.110

还有剩下的一个难题是还需要手动输入密码,这个怎么自动化呢?

1
2
3
# just for mac
brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb
sshpass -p "PASSWORD" ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no root@192.168.37.110

或者使用 Fabric 等远程执行 run(“cmd”)

1
2
# tips 执行 sudo 不需要手动输入密码
echo "PASSWORD" | sudo -S CMD

用 iterm2 做 terminal 管理

参考:

枚举的特殊用法 - 杨志平

源于项目中的应用太广了,但是对swift的很多简单特性不熟。之前那个动画的阶段使用到enum有遇到困难暂时绕开它了

当时的目标就是外部直接赋值操作

如下动画的enum示例:

为了省事,目前直接使用死的文案放在这里

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
enum AnimationPeriod: UInt {
// 动画执行的五个阶段
case Start,First,Second,Third,End

func description() -> String {
switch self {
case .Start, .First: return "正在提取学校最新\n录取条件"
case .Second: return "正在与学校进行匹配"
case .Third, .End: return "正在根据匹配结果\n生成选校方案"
}
}

func duration() -> NSTimeInterval {
switch self {
case .Start: return 0.8
case .First: return 1
case .Second: return 2
case .Third: return 0.5
case .End: return 0.25
}
}
}

extension AnimationPeriod {
mutating func next() {
switch self {
case .Start: self = .First
case .First: self = .Second
case .Second: self = .Third
case .Third: self = .End
default: self = .End
}
}
}

下面我们看看一些枚举的使用

携带参数

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
enum FamilyType {

case Father(age: Int)
case Mother(age: Int)
case Sister(age: Int)

func gift() -> String {
switch(self) {
case .Sister(let age):
if age > 15 {
return "iphone"
} else {
return "toy"
}
case .Mother(let age) where age < 40:
return "cloth"
default:
return "book"
}
}
}

let someone = FamilyType.Sister(age: 11)
let somebody = FamilyType.Mother(age: 40)
// swift的枚举技巧
let someoneGift = someone.gift() // print toy
let somebodyGift = somebody.gift() // book

那我们要取值的有

  • 方法一
1
2
3
4
5
6
7
switch someone {
case .Father(let age):
age
case .Sister(let age):
age
default:()
}
  • 方法二
1
2
3
if case .Sister(let age) = someone {
age
}

枚举的嵌套

1
2
3
4
5
6
7
8
9
10
11
enum Colleague {
enum Weight: Int {
case Light
case Mid
case Heavy
}
case iOS(weight: Weight)
case Android(weight: Weight)
case HTML(weight: Weight)
}
let woodenHelmet = Colleague.iOS(weight: .Mid)

枚举的成员变量

之前就一直想要使用枚举做到外部动态对枚举赋值储存操作,
那成员变量用法如下

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
// 根据自身赋值
enum Device {
case iPad, iPhone
var year: Int {
switch self {
case iPhone: return 2007
case iPad: return 2010
}
}
}

// set get 方法对于枚举的成员变量是无效的,允许get调用但set不可执行
enum Book {
case Story, News
var year: Int {
set{
year = newValue
}
get{
return self.year
}
}
}

let myIpad = Device.iPad
myIpad.year

var storyBook = Book.Story
//storyBook.year = 2010 // set 方法此处报错
//storyBook.year // get 无效

初始化,感觉然并软

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
enum AppleDevice {
case iMac(price:Int)
case iPod(price:Int)
case iPhone(price:Int)
init (costMoney: Int) {
if costMoney > 10000 {
self = .iMac(price: costMoney)
} else if costMoney > 2500 {
self = .iPhone(price: costMoney)
} else {
self = .iPod(price: costMoney)
}
}
}

let myDevice = AppleDevice(costMoney: 6000)

元组的使用

多个参数的介入时,可以使用元组,此处常规使用报错暂时无法解决,
使用func函数赋值倒是没有出错。why??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum HumanHabit {
case Reading
case PlayGame
case Traveling
}
typealias HumanInfo = (age: Int, name: String, habit: HumanHabit)

func selectRAM(humanInfo: HumanInfo) -> HumanInfo {return (age: 32, name: humanInfo.name, habit: humanInfo.habit)}
func selectCPU(humanInfo: HumanInfo) -> HumanInfo {return (age: humanInfo.age, name: "3.2GHZ", habit: humanInfo.habit)}
func selectGPU(humanInfo: HumanInfo) -> HumanInfo {return (age: humanInfo.age, name: "3.2GHZ", habit: .Reading)}

enum Desktop {
case Cube(HumanInfo)
case Tower(HumanInfo)
case Rack(HumanInfo)
}

let aTower = Desktop.Tower(selectGPU(selectCPU(selectRAM((0, "", .Traveling) as HumanInfo))))