使用 nodejs + zx 编写脚本更新本地 hosts


字数:1.2k 阅读时长:6分钟 阅读:85

在日常的开发和运维工作中,我们经常需要修改本地的 hosts 文件来实现一些特定的网络配置,比如将某个域名指向特定的 IP 地址。而使用 Node.js 结合 zx 工具可以让我们更轻松地编写和运行脚本来更新本地的 hosts 文件。

nodejs zx shell

一、功能介绍

目标: 通过修改 Hosts 解决国内 Github 经常抽风访问不到的情况

  1. 获取 github 上的远程 hosts 文件内容,更新本地 hosts 文件
  2. 恢复系统原有 hosts 文件
  3. 刷新 DNS 缓存,使配置生效

二、准备工作

首先,确保你已经安装了 Node.jsnpm。然后,通过 npm 安装 zx 工具:

1
npm install -g zx

三、编写脚本

接下来,我们来编写一个简单的 Node.js 脚本,使用 zx 来更新本地的 hosts 文件。以下是一个示例脚本,可以根据实际需求进行修改:

  1. 更新 hosts 脚本 update-hosts.mjs
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
#!/usr/bin/env zx

import { $, spinner } from 'zx'
import axios from 'axios'
import chalk from 'chalk'
import { dir, hostsPath, sh, startStr, endStr } from './config/hosts.config.mjs'

// 远程获取 hosts 文件内容,
async function getHostsContent() {
try {
const response = await axios({
url: `https://api.github.com/repos/maxiaof/github-hosts/contents/hosts`,
})
console.log(response.data.content)
// await $`echo ${response.data.content} > ${dir}/base64.txt`
const readmeContent = Buffer.from(response.data.content, 'base64').toString(
'utf-8'
)
return readmeContent
} catch (error) {
console.error('Error fetching README:', error.message)
}
}

async function saveReadmeFile() {
try {
const response = await axios({
url: `https://api.github.com/repos/maxiaof/github-hosts/contents/README.md`,
})
const readmeContent = Buffer.from(response.data.content, 'base64').toString(
'utf-8'
)
await $`echo ${readmeContent} > ${dir}/README.md`
} catch (e) {
console.log(e)
}
}

async function readLine(str = '') {
let hosts = ''
let isHosts = false
str.split('\n').forEach(line => {
if (line.includes(startStr)) {
isHosts = true
}
if (isHosts) {
hosts += `${line}\n`
}
if (line.includes(endStr)) {
isHosts = false
}
})

return hosts
}

async function runShell(hosts) {
try {
console.log(hosts)
// await $`pwd`
// 写入 github hosts
await $`echo ${hosts} > ./host/github.hosts`
// 复制系统原有 hosts 到新 hosts
await $`cp -f ./host/base.hosts ./host/hosts`
// 在新 hosts 后追加 github hosts
await $`cat ./host/github.hosts >> ./host/hosts`
// 复制新 hosts 到 /etc/hosts
await $`cp -f ./host/hosts ${hostsPath}`
// 刷新DNS,激活生效
await $`echo ${sh}`
} catch (p) {
console.log(`Exit code: ${p.exitCode}`)
console.log(`Error: ${p.stderr}`)
await $`exit 1`
}
}

async function initHostsFile() {
try {
let error = (await $`ls ${dir}`).stderr
if (!error) {
console.log(`${dir} 文件夹已存在`)
}
} catch (err) {
console.log('文件夹不存在')
await $`mkdir ${dir}`
// 下载保存 README.md
await saveReadmeFile()
// 备份系统 hosts
await $`sudo cp ${hostsPath} ${dir}/os.hosts`
// 第一次初始化,把系统 hosts 作为 base.hosts
await $`sudo cp ${hostsPath} ${dir}/base.hosts`
await $`touch ${dir}/github.hosts`
await $`touch ${dir}/hosts`
}
}

!(async function run() {
// 初始化目录文件
await initHostsFile()
await spinner('running...', async () => {
let hosts = await getHostsContent()
await runShell(hosts)
})
await spinner('running...', () => $`sleep 2`)
console.log(chalk.green('Local hosts updated successfully!'))
})()
  1. 恢复系统 hosts 脚本 reset-hosts.mjs
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
#!/usr/bin/env zx

// // eslint-disable-next-line
// /* eslint-disable */
import { $, spinner } from 'zx' // eslint-disable-line
import chalk from 'chalk'
import { dir, hostsPath, sh } from './config/hosts.config.mjs'

async function runShell() {
try {
await $`ls ${dir}`
// 复制基础 hosts 到新 hosts
await $`cp -f ./host/base.hosts ./host/hosts`
// 复制新 hosts 到 /etc/hosts
await $`cp -f ./host/hosts ${hostsPath}`
// 刷新DNS,激活生效
await $`echo ${sh}`
} catch (p) {
console.log(`Exit code: ${p.exitCode}`)
console.log(`Error: ${p.stderr}`)
await $`exit 1`
}
}

!(async function run() {
await spinner('running...', async () => {
await runShell()
})
await spinner('running...', () => $`sleep 2`)
console.log(chalk.green('Local hosts reset successfully!'))
})()
  1. 配置文件 hosts.config.mjs
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
export const osMap = {
darwin: {
name: 'MacOS',
hostsPath: '/etc/hosts',
sh: 'sudo killall -HUP mDNSResponder',
},
linux: {
name: 'Linux',
hostsPath: '/etc/hosts',
sh: 'sudo nscd restart',
},
win32: {
name: 'Windows',
hostsPath: 'C:/Windows/System32/drivers/etc/hosts',
sh: 'ipconfig /flushdns',
},
}

export const dir = './host'

export const { platform } = process

export const { hostsPath, sh } = osMap[platform]

export const startStr = '#Github Hosts Start'

export const endStr = '#Github Hosts End'

四、运行脚本

运行脚本有两种方式:

  1. update-hosts.mjsreset-hosts.mjs 脚本作为可执行文件,前提是全局安装了 zx 工具
  2. 使用 node 命令运行脚本,需要本地安装 axioschalkzx 等依赖

方式一:可执行文件执行

赋予执行权限:

1
2
chmod +x update-hosts.mjs
chmod +x reset-hosts.mjs

然后在终端中运行该脚本:

1
2
3
./updateHosts.js
# 或
./resetHosts.js

方式二:node 命令执行

1
2
3
4
5
node update-hosts.mjs
node reset-hosts.mjs
# sudo 权限执行(MacOS)
sudo node update-hosts.mjs
sudo node reset-hosts.mjs

其中涉及 sudo 权限(MacOS),需要输入密码。
windows 系统下,需要管理员权限运行,或以管理员身份运行终端 cmd。

参考文档:


欢迎访问:天问博客

本文作者: Tiven
发布时间: 2024-03-26
最后更新: 2024-03-26
本文标题: 使用 nodejs + zx 编写脚本更新本地 hosts
本文链接: https://www.tiven.cn/p/f948037b/
版权声明: 本作品采用 CC BY-NC-SA 4.0 许可协议进行许可。转载请注明出处!
欢迎留言,提问 ^_^
个人邮箱: tw.email@qq.com
notification icon
博客有更新,将会发送通知给您!