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

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

nodejs zx shell

一、功能介绍

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

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

二、准备工作

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

npm install -g zx

三、编写脚本

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

  1. 更新 hosts 脚本 update-hosts.mjs
#!/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
#!/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
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 等依赖

方式一:可执行文件执行

赋予执行权限:

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

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

./updateHosts.js
# 或
./resetHosts.js

方式二:node 命令执行

node update-hosts.mjs
node reset-hosts.mjs
# sudo 权限执行(MacOS)
sudo node update-hosts.mjs
sudo node reset-hosts.mjs

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

参考文档:

  • https://google.github.io/zx/
  • https://www.npmjs.com/package/zx

欢迎访问:天问博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/490054.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

黑马头条day5总结

1、surefire-reports for the individual test results. 借鉴:【已解决】surefire-reports for the individual test results.-CSDN博客 Please refer to D:\javashizhan01\heima-leadnews\heima-leadnews-service\heima-leadnews-article\target\surefire-report…

【jenkins+cmake+svn管理c++项目】Windows环境安装以及工具配置

一、目标和环境 目标:搭建一个jenkins环境,实现jenkins调用cmake和svn和VS编译c项目,并将生成的库上传svn。 环境:win10虚拟机(练习流程用,正式用的话还是放到服务器),VS2017. 二、…

54、Qt/对话框、事件机制相关学习20240325

一、完善对话框,点击登录按钮,如果账号和密码匹配,则弹出信息对话框,给出提示”登录成功“,提供一个Ok按钮,用户点击Ok后,关闭登录界面,跳转到其他界面 如果账号和密码不匹配&#…

四大AI神器,助你开启智慧家居新生活

曾经,人工智能还只是科幻电影里的未来幻想,而今,它已悄然融入我们生活的方方面面。不再只是工厂里的自动化手臂,或是电影中的情感机器人,AI技术已经走进了寻常百姓家,让家居生活也焕发出智慧的光彩。 想象…

并发-多线程

目录 进程 线程 线程的串行 区别 多线程 进程 是指计算机中已执行的程序,曾经是分时系统的基本运作单位在面向进程设计的系统(如早期的UNIX,Linux 2.4及更早的版本)中,是程序的基本执行实体在面向线程设计的系统…

【PL理论】(1) 语法与语义:归纳的定义 | 推理规则 | 推导树 | 数学归纳法证明 (MI)

💭 写在前面:在学习编程的过程中,我们经常会听到 "语法" 和 "语义" 这两个词,这对于理解和编写高质量的代码至关重要。在本博客中,我们将深入探讨这两个概念,从而帮助读者更好地理解编…

趣味算法,猴子算法。python如何实现猴子算法

给一只猴子一台打印机,虽然这只猴子根本不识字,但会乱按,经过一段时间后,在它乱按出来的单词里总能找到一些至少看起来是有意义的部分,比如一两个简短的单词,由此可以推出:只要给它足够长的时间…

vite+vue3动态模块化导入并使用pinia

一、安装引入pinia 1.安装 pnpm install pinia # 或者使用 yarn yarn add pinia # 或者使用 npm npm install pinia 2.在main.js里引入 import { createApp } from vue import App from ./App.vue import { createPinia } from pinia createApp(App).use(createPinia()).mo…

辽渤湾海现已加入2024第七届燕窝天然滋补品博览会

参展企业介绍 大连辽渤湾海产品有限公司,是一家主营海参、鲍鱼、海胆等大连海产品的加工和销售的综合型水产企业,拥有国内精良的整条加工流水线,拥有上千平米的现代化加工办公场地的现代化企业。现已发展成为大连海参产品的主导型深加工基地。…

如何清理释放群晖客户端缓存?

任正菲说:企业最大的浪费,是经验的浪费! 而一个一个的经验,又都来自企业的每一个工作者。 因此当我们在工作过程中遇到一些问题时,我们就应该下意识的把解决问题的经验沉淀下来,从而可以与大家进行分享。…

软件设计师19--文件管理

软件设计师19--文件管理 考点1:文件相关概念例题: 考点2:树形目录结构(绝对路径与相对路径)例题: 考点3:位示图例题: 考点4:索引文件索引文件结构例题: 考点1…

武汉星起航:跨境电商行业的领军者,互帮互助共创佳绩

武汉星起航电子商务有限公司,作为跨境电商行业的领军者,以其出色的业绩和卓越的团队实力,在业内赢得了广泛的赞誉。公司自运营团队在亚马逊平台上成功开设了多家店铺,凭借着深耕跨境电商行业多年所积累的经验,取得了令…

[自研开源] 数据集成之分批传输 v0.7

开源地址:gitee | github 详细介绍:MyData 基于 Web API 的数据集成平台 部署文档:用 Docker 部署 MyData 使用手册:MyData 使用手册 试用体验:https://demo.mydata.work 交流Q群:430089673 介绍 本篇基于…

面试笔记——Java集合篇

Java集合框架体系 重点:单列集合——ArrayList、LinkedList;双列集合——HashMap、ConcurrentHashMap。 List相关 数组(Array) 是一种用连续的内存空间存储相同数据类型数据的线性数据结构。 数组获取其他元素: 为什…

为什么在vite中使用eslint报错‘__dirname‘ is not defined?

问题分析 发生这种情况是因为 ESLint 不知道 vite.config.js 中的代码在 Node.js 中使用,__dirname 未在浏览器中定义,也未在 ES 模块中定义。因此要告诉 ESLint 代码将作为 CommonJS 模块在 Node.js 中运行。 解决方案 请打开 ESLint 配置并在该 env …

关于 boost::asio::strand 初始化 socket、stream、resolver、deadline_timer 对象

在 boost::asio 之中默认情况下,大家使用 io_context 来为这些对象初始化传递的执行者,但我需要这里说明。 对于 boost::asio 构造类似 socket 对象必须构造传递 io_context 是个伪命题,boost::asio 对象并非只允许传递 boost::asio::io_cont…

pyrealsense2获取保存点云

一、第一种实现代码 Python import sys import cv2 import pyrealsense2 as rs import numpy as np import keyboard import open3d as o3d import osif __name__ "__main__":output_folder output_data/os.makedirs(output_folder, exist_okTrue)pipeline rs.p…

git cherry pick merge部分提交

cherry pick merge 指定某次提交 1. git history 选择要从哪个分支merge 2. 找到提交记录,选择cherry pick 3.这个时候就可以直接push了

【面试题】ES文档写入和读取流程详解

前言:在回答这个问题之前我们先要搞清楚一个问题那就是什么是文档,避免不知所云! 一、什么是文档? 在Elasticsearch中,文档(Document)是最基本的信息单元,用于表示和存储数据。文…

数据采集用,集成了主流工业通讯协议

IoTClient 是一个物联网设备通讯协议实现客户端,集成了主流工业通讯协议,包括主流PLC通信读取、ModBus协议、Bacnet协议等。该组件基于.NET Standard 2.0,适用于.NET的跨平台开发,可在Windows、Linux等系统上运行,甚至…