BNU-FZH

fengzhenhua@outlook.com

作为一名科研人员,从一些知名期刊下载论文是一个重要的工作。然而,有些网站要么打不开,要么特别慢,然后这些科研网站又都是正规的网站。本文发布一款shell脚本来彻底解决这一痛点。

注意:本文发布有脚本目前仅支持Arch Linux,主要是安装依赖关系,其他Linux发行版可以自行修改。暂无发布Windows版的计划,如果您可以用Python实现对Windows的支持,欢迎联系本人共同拓展syndns.sh.

脚本编写思路

当前的网络设备已经完全可以满足大众上网的需求,一些网站为了增加功能等,会默认调用大量的js脚本等,因此打开这个网站时就会附加后台打开若干网站。通过后台链接传输的数据不是很大,现行的网速完全可以几乎瞬时完成,造成访问不畅通的瓶颈在于DNS,因为DNS不断的去解析这些网站包括的所有域名,在来来回回的解析过程中耽误了大量的时间,所以本脚本的核心思路在于解决DNS解析痛点。 整体方法包括:

  • 针对大众: 根据大家常用的网站,把这些网站的IP和域名统一写入本地/etc/hosts, 这样每次访问这些高频网站,系统就会从本地寻址,加快了解析速度。
  • 针对个人: 从firefox导出近几个月的历史记录~/bookmarks-2024-12-02.json, 然后执行syndns, 脚本自动从历史记录中把您自己常用的网站通过谷歌的8.8.8.8解析出可靠的IP列表,并写入到本地文件~/.host_dns_autoadd.txt, 然后syndns会把它载入到内存供dnsmasq调用。
  • 安装 dnsmasq 并启用,实现本地作为 DNS 服务器的功能,同时把 /etc/hosts~/.host_dns_autoadd.txt 中的映射关系统一放入内存 /dev/shm/dnsrecord.txt 文件中, 之后 dnsmasq 每次查询IP就会读取一次文件 /dev/shm/dnsrecord.txt , 而这成为最快的方式。如果不调入内存,那每次查询 IP , 系统都会去读取 /etc/hosts, 这个文件位于硬盘上,所以它的读取速度不是最快的,相对而言固态硬盘要比机械硬盘好很多,但是仍然远不如内存快, 所以调入内存是终极大招。

脚本源码

本文发布之时(2024年12月02日) syndns.sh 版本为 V1.5 , 最新脚本请前往:

syndns.sh
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
108
109
#! /bin/sh
#
# Program : syndns.sh
# Version : v1.5
# Date : 2024-12-02 11:20
# Author : fengzhenhua
# Email : fengzhenhua@outlook.com
# CopyRight: Copyright (C) 2022-2025 FengZhenhua(冯振华)
# License : Distributed under terms of the MIT license.
#
# 检测软件依懒, 若未检测到,则自动安装
SYNDNS_DEPEND(){
for VAR in $1 ;do
pacman -Qq $VAR &> /dev/null
if [[ $? != 0 ]]; then
sudo pacman -S $VAR
fi
done
}
# 变量
SYN_EXE="/usr/local/bin/${0%.sh}"
SYN_AUTO="$HOME/.config/autostart/${0%.sh}.desktop"
SYN_SUDO="/etc/sudoers.d/01_$USER"
SYN_HOS="/etc/hosts"
SYN_REC=$(grep "addn-hosts" /etc/dnsmasq.conf |grep "/dev/shm/")
SYN_REC=${SYN_REC#*=}
SYN_ADD="$HOME/.host_dns_autoadd.txt"
#
# 主程序
SYNDNS_PROCESS(){
cat $SYN_HOS |grep -v '^$'|grep -v '^#'|sort |uniq -u > $SYN_REC
if [ -e $SYN_ADD ]; then
cat $SYN_ADD |grep '^[0-9]' |grep -v '^$'|grep -v '^#'|sort |uniq -u >> $SYN_REC
fi
echo "$(hostname -i) localhost:" >> $SYN_REC
systemctl is-active --quiet dnsmasq
if [[ $? == 0 ]]; then
sudo systemctl restart dnsmasq.service
else
sudo systemctl start dnsmasq.service
fi
}
# 安装和更新
if [ $# -gt 0 ]; then
if [ $1 == "-i" -o $1 == "-I" ]; then
SYNDNS_DEPEND "dnsutils inetutils dnsmasq jq"
sudo cp -f $0 $SYN_EXE
sudo chmod +x $SYN_EXE
if [ ! -e $SYN_AUTO ]; then
sudo touch $SYN_AUTO
cat > $SYN_AUTO <<EOF
[Desktop Entry]
Name=SynDns
TryExec=syndns
Exec=$SYN_EXE
Type=Application
Categories=GNOME;GTK;System;Utility;TerminalEmulator;
StartupNotify=true
X-Desktop-File-Install-Version=0.22
X-GNOME-Autostart-enabled=true
Hidden=false
NoDisplay=false
EOF
sudo sh -c "cat > /etc/dnsmasq.conf" <<EOA
domain-needed
bogus-priv
resolv-file=/etc/resolv.conf
no-poll
interface=lo
listen-address=127.0.0.1
bind-interfaces
no-hosts
addn-hosts=/dev/shm/dnsrecord.txt
cache-size=9999
port=53
EOA
fi
if [ ! -e $SYN_SUDO ]; then
sudo touch $SYN_SUDO
sudo sh -c "cat > $SYN_SUDO" <<EOB
$USER ALL=(ALL) NOPASSWD: /bin/systemctl start stirling-pdf.service, /bin/systemctl stop stirling-pdf.service, /bin/systemctl restart dnsmasq.service, /bin/systemctl start dnsmasq.service
EOB
fi
elif [[ $1 =~ ".json" ]]; then
Address=($(cat $1|jq -r '.children[]' |grep "\"uri\":"))
Address=(${Address[*]#*//})
Address=(${Address[*]/\"uri\":})
Address=(${Address[*]%%/*})
Address=(${Address[*]%%\"*})
Address=(${Address[*]%%*[0-9]}) # 去除非域名
Address=(`echo ${Address[@]}|sed -e 's/ /\n/g'|sort |uniq`)
if [ -e $SYN_ADD ]; then
rm $SYN_ADD
fi
touch $SYN_ADD
for i in ${Address[*]} ; do
unset SYN_IP
SYN_IP=($(dig @8.8.8.8 +short $i)) # 默认从Google Public DNS 解析历史IP
SYN_IP=(${SYN_IP[*]%%*\.})
for ipc in ${SYN_IP[*]}; do
echo "$ipc $i" >> $SYN_ADD
let j+=1
done
done
SYNDNS_PROCESS
fi
fi
# 默认执行主程序
SYNDNS_PROCESS

使用方法

  1. 将上述脚本 syndns.sh 保存到本地,并赋于执行权限
    1
    sudo chmod+x syndns.sh
  2. 安装脚本
    1
    syndns.sh -i
  3. 导入由firefox生成的历史记录文件:
    1
    syndns ~/bookmarks-2024-12-02.json

注意:Firefox 生成历史记录文件方法,历史管理历史导入和备份备份...

参考文章

awk是一个强大的文本处理工具,它可以根据指定的字段来操作和处理文本数据。下面是使用awk命令去除重复行的步骤:

  1. 使用grep命令搜索匹配的行,并使用awk命令打印其中的一列。
1
grep “pattern” file.txt | awk ‘{print $1}’ > temp.txt  

其中,pattern是你要匹配的模式,file.txt是要搜索的文件,$1表示打印第一列。

  1. 使用sort命令对临时文件进行排序。
1
sort temp.txt > sorted.txt  
  1. 使用uniq命令去除重复行。
1
uniq sorted.txt > result.txt  
  1. 可选:删除临时文件。
1
rm temp.txt sorted.txt  

这样,就可以得到一个去除重复行的结果文件result.txt。

注意: 使用grep命令去除重复行是一种简单的方法,但是它只能根据整行进行去重。如果你需要根据特定的字段或者条件来去重,可以使用其他更强大的工具,如awk、sed或者perl等。

在Linux中,可以使用grep命令去除重复行。grep命令是一个强大的文本搜索工具,但是默认情况下它只会输出匹配的行,而不会去除重复的行。要去除重复行,可以使用grep命令的-v选项结合sortuniq命令来实现。

下面是使用grep命令去除重复行的步骤:

  1. 使用grep命令搜索匹配的行,将输出重定向到一个临时文件。
1
grep “pattern” file.txt > temp.txt  

其中,pattern是你要匹配的模式,file.txt是要搜索的文件。

  1. 使用sort命令对临时文件进行排序。
1
sort temp.txt > sorted.txt  
  1. 使用uniq命令去除重复行。
1
uniq sorted.txt > result.txt  
  1. 可选:删除临时文件。
1
rm temp.txt sorted.txt  

这样,就可以得到一个去除重复行的结果文件result.txt。

本博客已经持续写了三四年了,最初根据网上的教程安装好后就把各种配置写到了自动化脚本 diary.sh 中,然而最近发现升级脚本后会有一串由node.js发出的错误。为了解决这个错误,不断的排除各种小问题,最终决定重新写一下配置博客的基本教程。

Node.js 和 Hexo 简介

Node.js是作为 Hexo程序的依赖而安装的,但是它报错了,经过网络搜索后发现,这是由于我的电脑中安装了最新的Node.js导致的。官网介绍:Node.js® 是一个免费、开源、跨平台的 JavaScript 运行时环境, 它让开发人员能够创建服务器 Web 应用、命令行工具和脚本。 而 Hexo 是一个部署博客的工具,而博客也是发布于网络上的一个 Web 页,所认这个依赖关系就清楚了。

Hexo 的作用是: 把作者写好的 Markdown 文件,使用Node.js渲染成 Web 页,进而可以在网站服务器上部署,实现网络访问的目标。

安装依赖软件

使用 pacman 安装的软件

1
sudo pacman -S nodejs-lts-jod npm git pandoc
  • git 是一个在github上管理源码的必备工具,详细使用请稳步: Git 教程
  • nodejs共有三个版本,分别是nodejs 23.1.0-1(最新版)、nodejs-lts-iron(最新长期支持版)、nodejs-lts-hydrogen(旧的长期支持版). 由于最新版不断有功能添加,其相当不稳定,今天的错误就是由它造成的。旧的长期支持版,又可能不兼容最新的软件,所以安装最新长期支持版就是一个最佳选择。
  • npm 是一个nodejs包管理器,使用它可以安装各种模块,这就很容易为博客添加新的功能。
  • pandoc If you need to convert files from one markup format into another, pandoc is your swiss-army knife.
  • 2025年03月29日, nodejs-lts-iron维护进入倒计时,因此今天升级到新的长期支持版nodejs-lts-jod.

使用 nodejs 包管理器安装的软件

npm 切换国内源

1
2
3
4
# 国内 淘宝 镜像源
npm config set registry https://registry.npmmirror.com/
# 官方镜像源
npm config set registry https://registry.npmjs.org/

阿里更换了淘宝镜像的域名,原域名https://registry.npm.taobao.org的 SSL 证书已经过期了(2024/01/22),所以我们需要更换最新的源.

安装更好用的包管理器 yarn

1
2
3
4
# 通过 pacman 安装
sudo pacman -S yarn
# 通过 npm 安装
sudo npm install yarn -g

注意:npmJavaScript自带的包管理器,拥有庞大的包注册表,但在性能和安全性方面相对较弱, 特别是下载安装模块的速度相当感人。Yarn 是由 Facebook、Google 等公司共同创建的,旨在解决 npm 的一些痛点,提供更快、更安全、更可靠的包管理体验, 其下载模块非常迅速,所以值得推荐。此外还有pnpm包管理器,但是由于它为了节省硬盘空间而做出了相当大的改变,这导致一些依赖问题不是很好解决,因此不推荐。这三个的区别和优缺点细节,请大家参考本文末的参考文章。

配置 hexo

设置 yarn 的国内源

1
2
3
4
# 国内 淘宝 镜像源
yarn config set registry https://registry.npmmirror.com/
# 官方镜像源
yarn config set registry https://registry.yarnpkg.com/

安装 nrm 镜像源工具

1
sudo yarn global add nrm

nrm使用方法,请参考本文末参考文章。使用nrm test列出各源,并给出源的网速,使用nrm use huawei切换到速度最快的华为源。

安装 hexo 命令

推荐使用速度更快的 yarn
1
2
3
4
# 使用yarn 安装
sudo yarn global add hexo-cli
# 使用 npm 安装
sudo npm install hexo-cli -g

设置本地博客站点

配置 hexo 默认站点

1
2
3
4
mkdir hexo-source
cd ./hexo-source
hexo init
hexo s

完成上面的操作后,在浏览器地址栏输入上述命令生成的本地地址 localhost:4000 就可以看到默认的博客了。

安装 Next 主题

1
2
3
4
cd hexo-source
git clone https://github.com/next-theme/hexo-theme-next themes/next
cd themes/next
git checkout $(git describe --tags $(git rev-list --tags --max-count=1))

切换为 Next 主题

Like all Hexo themes, after you download it, open Hexo config file, find theme option, and change its value to next (or another theme directory name).

hexo-source/_config.yml
1
2
cd hexo-source
theme: next

2024年11月30日, 在测试上述步骤时,发现 启动报错 Cannot find module 'css', 据github上的信息,解决方法是:css 应该被作为 stylus 的依赖包安装。你可以试试重新安装 hexo-renderer-stylus

1
2
3
4
cd hexo-source
yarn add hexo-renderer-stylus
# 也可以使用 npm
npm i hexo-renderer-stylus

本地启动检测

1
2
3
hexo clean 
hexo g
hexo s

参考文章

命令安装

以前net-tools属于base组,装base时自动就装上了,现在哪个组都不属于了,这些工具需要单独安装。其中ifconfig、route在net-tools包中,nslookup、dig在dnsutils包中,ftp、telnet等在inetutils包中,ip命令在iproute2包中。

1
sudo pacman -S net-tools dnsutils inetutils iproute2

参考文章

简介

《REVTEX 4 作者指南》是美国物理学会(APS)提供的,用于指导如何使用 REVTEX 4 来准备向 APS 期刊提交的手稿。在 TexLive已经收录,所以安装TexLive后,直接调用模板就可以了。

模板

这个模板是我写作时采用的,列在此处大家可以直接调用。

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
\documentclass[aps,pre,showpacs,preprint,superscriptaddress]{revtex4-1}
\usepackage{graphicx}
\usepackage{subfigure}
\usepackage{amsmath}
\usepackage{ulem}
\usepackage{bm}
\usepackage{amssymb}
\usepackage{color}
\usepackage{epstopdf}
\usepackage{epsfig,dsfont,multirow}
\usepackage{physics}
\usepackage{tikz}
\usetikzlibrary{fadings,patterns}
\usepackage{float}
\usepackage[
pdfborder={0 0 0},
bookmarksnumbered=true,
pagebackref,
pdftex
]{hyperref}
\usepackage{orcidlink}

\begin{document}
\title{Your Article Title}
\author{YourName\,\orcidlink{0000-0000-0000-0000}}
\email[Contact author:]{YourEmail@xxx.com}
\homepage[Visit:]{https://YourHomePageSite}
\affiliation{School of Physics and Astronomy, Beijing Normal University, Beijing 100875, China}
% \thanks{miscellaneous text}
\date{\today}
\preprint{Preprint}
\keywords{electron-positron; laser}
\begin{abstract}
Your abstract
\end{abstract}

% \pacs{05.45.-a; 02.60.-x; preprint}

\maketitle

\section{Introduction}

\section{Reference}


\bibliographystyle{unsrt}
\bibliography{Reference.bib}
%
% 直接写引用信息,不推荐
%
% \appendix
%
% \begin{thebibliography}{99}\suppressfloats
%
% \bibitem{ComDyn}
% L. Carleson, T. W. Gamelin, Complex Dynamics, Springer, New York,
% NY, 1993.
%
% \bibitem{AITJF}
% S. Sutherland, An Introduction to Julia and Fatou Sets, in: C. Bandt,
% M. Barnsley, R. Devaney, K. J. Falconer, V. Kannan, V. Kumar P.B.
% (Eds.), Fractals, Wavelets, and their Applications, Springer Proceedings
% in Mathematics $\&$ Statistics, Springer International Publishing, Cham,
% pp. 37-60, 2014.
%
% \bibitem{MJFO}
% M.-F. Danca, M. Fečkan, Mandelbrot set and Julia sets of fractional order, Nonlinear Dynamics 111(10), 9555-9570 (2023).
%
% \bibitem{MSPPCRF}
% A. J. Mitchell, Existence of the Mandelbrot Set in the Parameter Planes of Certain Rational Functions, Theses and Dissertations, University of Wisconsin-Milwaukee (2016).
%
% \bibitem{GBBM}
% H. Jang, Y. So, S. M. Marotta, Generalized baby Mandelbrot sets adorned with halos in families of rational maps, Journal of Difference Equations and Applications 23(3), 503-520 (2017).
%
% \end{thebibliography}
\end{document}

重要宏包

用来插入作者的orcid, 调用和命令

1
2
\usepackage{orcidlink}
\orcidlink{0000-0000-0000-0000}

2. float

在LaTex中,\begin{figure}[htbp]是图片环境,常用选择项[htbp]是浮动格式:

  • [h] here,当前位置。将图形放置在正文文本中给出该图形环境的地方。如果本页所剩页面不够,这一参数将不起作用。
  • [t] top,顶部。将图形放置在页面的顶部。
  • [b] bottom,底部。将图形放置在页面的底部。
  • [p] page of its own,浮动页。将图形放置在一个允许有浮动对象的页面上。

一般使用[htb]这样的组合,只用[h]是没有用的。这样组合的意思就是LaTex会尽量满足排在前面的浮动格式,就是h-t-b这个顺序,让排版的效果尽量好。

[!h]只是试图放在当前位置。如果页面剩下的部分放不下,还是会跑到下一页的。一般而言,用[!h]选项通常会出现不能正确放置的问题,所以常用[ht][htbp]等, 这里加感叹号的意思是 忽略 “美学” 标准。

如果你确实需要把图片放在当前位置,不容改变,可以用 \usepackege{float} 宏包的[H]选项。不过如果这样做,出现放不下的问题时需要手工调整。使用格式如下。

1
2
3
4
5
\usepackage{float} 
% ...
\begin{figure}[H]
foo
\end{figure}

特别强调,当表格或者图片占据双栏模板的两栏时(即在\begin{table*}时),这些控制选项就失效了。其他情况请参考 技能提升之Latex控制图片位置

参考文章

通俗解释 DNS

DNS (Domain Name System) 是域名系统的缩写,它作为可以将域名和 IP 地址相互映射的一个分布式数据库。通俗来讲,互联网上每台电脑都会有一个身份证号来标记电脑,然后电脑相互访问时就需要知道这个身份证号才能到达指定的电脑,这个身份证号就是IP地址。但是,如果仅仅是有限的几台电脑,这个方法足够应对了,然而互联网上有无数的电脑,每次访问某台电脑,就需要查询这台电脑的 IP, 显然一个人不可能记住那么多的IP地址。为了方便人的记忆,我们可以为 IP 起一个别名,也就是域名,比如www.baidu.com,同时把IPwww.baidu.com的对应关系保存在/etc/hosts文件中。 这样每次电脑访问这台电脑时就直接访问www.baidu.com, 然后电脑就会去/etc/hosts查询这个域名对应的IP, 然后根据查到的IP访问对应的电脑。 然而,这样做以后,每个人的电脑就会保存不同的hosts文件,同时也需要每次访问新的电脑都要编辑这个hosts文件,世界很大,维护hosts会耽误大量的时间,同时若自己换了电脑,那必然也要带上这个自己习惯的hosts文件到新的电脑。为了解决这个问题,网络上出现了专门同步IP与域名对应关系的分布式服务器(也是一台电脑), 这台电脑就叫做 DNS 服务器。当我们知道了 DNS 服务器的 IP以后,把这个 IP告诉我们自己的电脑,这样每次访问互联网,我们自己的电脑就会向 DNS 服务器发出申请,返回相应域名的 IP地址,然后再通过这个IP访问域名对应的电脑, 于是hosts文件实现了全网同步。但是,随之而来的问题是 DNS 服务器的性能会因不同的设备而有差异,同时不同 DNS 服务器也会因为通信线路和地理位置等造成访问速度不同,我们肯定希望速度越快越好,于是人们就需要选择那些可靠的大厂 DNS 服务器。

提升网络访问速度

随着互联网的发展,全球的电脑越来越多,同一个网站为了更好的展示效果和更强大的功能而链接到多个网站。有时候,我们可以快速打开一个网站,但是它会花相当长的时间来打开完整的网站,这个体验就不是很好了。 事实上,DNS 服务器再快也不会比自己电脑上保存了hosts文件快,似乎问题又回到了最初,但是又不一样。为了提高访问速度,我们可以通过某些软件记录下每次访问过的域名和相应的IP地址,这样第二次以后速度会实现质的飞越。同时,现在的硬盘价格也是相当便宜,我们平时游览的网站通常也是和自己相关领域的有限数目的网站,因此使用软件自动缓存下这些访问过的记录也是一件相当容易的事情,这会给我们网上冲浪带来质的飞越。

全自动安装脚本

如果您使用的是ArchLinux, 同时不想关注细节,请直接保存脚本syndns.sh后,执行sudo chmod +x syndns.sh && ./syndns -i , 即可一键配置好本地dns缓存。

syndns.sh
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
#! /bin/sh
#
# Program : syndns.sh
# Version : v1.1
# Date : 2024-11-30 00:52
# Author : fengzhenhua
# Email : fengzhenhua@outlook.com
# CopyRight: Copyright (C) 2022-2025 FengZhenhua(冯振华)
# License : Distributed under terms of the MIT license.
#
# 检测软件依懒, 若未检测到,则自动安装
SYNDNS_DEPEND(){
for VAR in $1 ;do
if [[ "$(pacman -Q |grep $VAR)" = "" ]]; then
sudo pacman -S $VAR
fi
done
}
SYN_EXE="/usr/local/bin/${0%.sh}"
SYN_AUTO="$HOME/.config/autostart/${0%.sh}.desktop"
SYN_SUDO="/etc/sudoers.d/01_$USER"
if [ $# -gt 0 ]; then
if [ $1 == "-i" -o $1 == "-I" ]; then
SYNDNS_DEPEND "inetutils dnsmasq"
sudo cp -f $0 $SYN_EXE
sudo chmod +x $SYN_EXE
if [ ! -e $SYN_AUTO ]; then
sudo touch $SYN_AUTO
cat > $SYN_AUTO <<EOF
[Desktop Entry]
Name=SynDns
TryExec=syndns
Exec=$SYN_EXE
Type=Application
Categories=GNOME;GTK;System;Utility;TerminalEmulator;
StartupNotify=true
X-Desktop-File-Install-Version=0.22
X-GNOME-Autostart-enabled=true
Hidden=false
NoDisplay=false
EOF
sudo sh -c "cat > /etc/dnsmasq.conf" <<EOA
domain-needed
bogus-priv
resolv-file=/etc/resolv.conf
no-poll
interface=lo
listen-address=127.0.0.1
bind-interfaces
no-hosts
addn-hosts=/dev/shm/dnsrecord.txt
cache-size=9999
port=53
EOA
if [ ! -e $SYN_SUDO ]; then
sudo touch $SYN_SUDO
sudo sh -c "cat > $SYN_SUDO" <<EOB
$USER ALL=(ALL) NOPASSWD: /bin/systemctl restart dnsmasq.service, /bin/systemctl start dnsmasq.service
EOB
fi
fi
fi
fi
SYN_REC=$(grep "addn-hosts" /etc/dnsmasq.conf)
SYN_REC=${SYN_REC#*=}
cat /etc/hosts > $SYN_REC
echo "$(hostname -i) localhost:" >> $SYN_REC
sudo systemctl start dnsmasq.service

本脚本全自动配置好了dnsmasq, 但是若想达到自己快速访问自己习惯的网站,请在/etc/hosts文件中加入IP和域名映射,具体操作参见:Linux解决无法访问学术网站的问题

屏蔽广告

  • 建立屏蔽文件存放目录:sudo mkdir /etc/dnsmasq.d
  • 下载anti-Ad广告列表:
    1
    sudo curl -o /etc/dnsmasq.d/anti-ad-for-dnsmasq.conf https://anti-ad.net/anti-ad-for-dnsmasq.conf
  • 修改配置文件/etc/dnsmasq.conf:
    /etc/dnsmasq.conf
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    domain-needed
    bogus-priv
    resolv-file=/etc/resolv.conf
    no-poll
    interface=lo
    listen-address=127.0.0.1
    bind-interfaces
    no-hosts
    addn-hosts=/dev/shm/dnsrecord.txt
    addn-hosts=/etc/dnsmasq.d
    cache-size=9999
    port=53
  • 重启dnsmasq.service服务
    1
    sudo systemctl restart dnsmasq.service

技术细节

Linux 使用 dnsmasq 开启本地 dns 缓存

dnsmasq 是一个轻量组 DHCP 和缓存 DNS 服务器。

1. 安装 dnsmasq

1
sudo pacman -S dnsmasq

2. 配置 dnsmasq

dnsmasq 的主配置文件为/etc/dnsmasq.conf。一些配置 dns 缓存相关参数(更多参数说明见 https://thekelleys.org.uk/dnsmasq/docs/dnsmasq.conf.example/etc/dnsmasq.conf 内说明)

配置文件设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cat /etc/dnsmasq.conf

domain-needed

port=53

bogus-priv

interface=lo

bind-interfaces

listen-address=127.0.0.1

cache-size=4000

resolv-file=/etc/resolv.dnsmasq

no-poll

参数说明

(1)domain-needed

如果没有域名后缀的请求(即单个主机名的查询)会被忽略,不会被转发到上游 DNS 服务器。防止将无效的主机名查询发送到外部 DNS 服务器。

(2)port

绑定指定端口

(3)bogus-priv

阻止将私有 IP 地址范围的查询结果返回给客户端。如果上游 DNS 服务器返回的结果是私有 IP 地址,dnsmasq 会将其丢弃。防止意外将私有 IP 地址暴露在外部网络。

(4)interface=lo

指定 dnsmasq 仅监听在本地回环接口 lo 上。限制 dnsmasq 只在本机的回环接口上工作,不对外提供 DNS 服务,增加安全性。

(5)bind-interfaces

强制 dnsmasq 只绑定到配置中明确指定的接口(例如 lo)。确保 dnsmasq 只监听指定接口,防止不必要的接口绑定,增强控制和安全性。

(6)listen-address

指定 dnsmasq 应该监听 DNS 查询的 IP 地址。如果使用 dnsmasq 作为本地 DNS 缓存服务,设置为 127.0.0.1。

(7)resolv-file

设置包含上游 DNS 服务器的文件的路径,不打开的话,默认用 /etc/resolv.conf ,也可以直接指定,例如,我们在 /etc 中创建一个名为 resolv.dnsmasq 的文件,其内容如下:

cat /etc/resolv.dnsmasq

nameserver 8.8.8.8

这些配置将使 dnsmasq 能够从 8.8.8.8 查询 DNS 记录并在本地缓存。

(8)cache-size

定义要缓存的最大 DNS 记录数。

(9)no-resolv

dnsmasq不使用 /etc/resolv.conf 或者其他文件,不做上游DNS查询。取消注释此行以防止 dnsmasq 使用 /etc/resolv.conf 文件。

(10)no-poll

禁用 dnsmasq 对 /etc/resolv.dnsmasq 文件的持续轮询检查。提高性能,避免频繁检查该文件的变动。如果不经常修改该文件,这个选项可以避免不必要的文件系统访问。

3. 启用 dnsmasq 服务

1
sudo systemctl enable --now dnsmasq.service

4. 将默认 DNS 设置为 dnsmasq

如果已经取消注释 dnsmasq 配置中的 no-resolv 选项,则无需编辑 /etc/resolv.conf

注释掉所有涉及 nameserver 的行,并写入127.0.0.1到 /etc/resolv.conf,如下示例:

1
2
3
cat /etc/resolv.conf
# nameserver 8.8.8.8
nameserver 127.0.0.1

dnsmasq 性能优化

我们都知道Bind不配合数据库的情况下,经常需要重新载入并读取配置文件,这是造成性能低下的原因。根据这点教训,我们可以考虑不读取/etc/hosts文件。而是另外指定一个在共享内存里的文件,比如/dev/shm/dnsrecord.txt ,这样就不费劲了,又由于内存的非持久性,重启就消失,可以设置为开机启动服务,实现每次开机自动同步/etc/hosts文件到内存中。

1. 配置 dnsmasq

/etc/dnsmasq.conf
1
2
no-hosts
addn-hosts=/dev/shm/dnsrecord.txt

2. 创建同步脚本 syndns.sh

/usr/local/bin/syndns
1
2
3
4
5
6
7
8
9
#! /bin/sh
#
# syndns.sh
# Copyright (C) 2024 Zhen-hua Feng <fengzhenhua@outlook.com>
#
# Distributed under terms of the MIT license.
#
cat /etc/hosts > /dev/shm/dnsrecord.txt
sudo systemctl start dnsmasq.service

3. 提升权限

/etc/sudoers.d/01_feng
1
feng ALL=(ALL) NOPASSWD: /bin/systemctl restart dnsmasq.service, /bin/systemctl start dnsmasq.service

提升启动dnsmasq.service的开启权限后,开机启动服务就不再需要sudo输入密码了,这样做更加合理。

4. 设置开机时启动

~/.config/autostart/syndns.desktop
1
2
3
4
5
6
7
8
9
10
11
[Desktop Entry]
Name=SynDns
TryExec=syndns
Exec=/usr/local/bin/syndns
Type=Application
Categories=GNOME;GTK;System;Utility;TerminalEmulator;
StartupNotify=true
X-Desktop-File-Install-Version=0.22
X-GNOME-Autostart-enabled=true
Hidden=false
NoDisplay=false

由于本人的桌面环境是Gnome, 所以推荐使用此处的ArchLinux配置自启动程序的方法。同时,在尝试使用systemctl方案时并求成功,原因在于systemctl是系统级服务,启动时cat写入内存的文件dnsrecord.txt就属于具备root权限,因此由于cat权限不足而失败。

针对网站提速

将常用网站的域名和IP放置到 /etc/hosts 文件可以缩短主机访问 DNS服务器的时间,前面将这些常用网站添加到内存文件 /dev/shm/dnsrecord.txt 中,这极大的提高了电脑访问的速度,因为即使是固态硬盘,它的读取速度也是与内存无法相比的,而这个文件却占据很小内存,甚至可以忽略不计。但是,在访问某一网站时,由于网站会借助 cdn 等添加一些js组件,而这一部分会零星的占用不少时间去访问 DNS服务器。为了进一步提速,就需要我们将这些后台访问的网址域名也添加到/etc/hosts文件中。方法是:打开 firefox更多工具Web 开发者工具网络, 然后就可以看到后台访问的许多网站,手动把这些域名解析后有可能获取多个IP, 将这些IP使用Ping工具测速后,把最快的IP添加到hosts中。下次访问主网站,速度就飞起了。

另外需要注意的是:firefox设置隐私和安全→取消关闭Firfox时删除Cookie与网站数据. 这样设置后,下次在访问此网站,那些缓存好的图片等就不需要再次下载了,网站只下载那些发生变动的部分,因此这又可以进一步的提升访问速度。

参考文章

科研工作中需要经常访问学术网站,然而有时候却无法访问或速度太慢,以致于论文无法下载。为解决这一问题,本文提出修改/etc/hosts文件的方法。

解决追加内容到 hosts 时无权限问题

1. 使用子命令

1
2
3
4
5
sudo bash -c "cat >> /etc/hosts" << EOF
172.67.9.71 journals.aps.org
104.26.5.132 doi.org
66.22.61.221 iopscience.iop.org
EOF

2. 使用tee命令

1
2
3
4
5
sudo tee -a /etc/hosts > /dev/null <<EOF
172.67.9.71 journals.aps.org
104.26.5.132 doi.org
66.22.61.221 iopscience.iop.org
EOF

Ip 查询

注意:选择上述任意的一个网站,然后输入你要访问的学术网站的域名,查询到对应的IP地址,保存下来。

写入到 hosts

updatehost.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#! /bin/sh
#
# Program : updatehost.sh
# Version : v1.1
# Date : 2023-10-08
# Author : fengzhenhua
# Email : fengzhenhua@outlook.com
# CopyRight: Copyright (C) 2022-2025 FengZhenhua(冯振华)
# License : Distributed under terms of the MIT license.
#
OutHost="/etc/hosts"
sudo curl -o $OutHost https://gitlab.com/ineo6/hosts/-/raw/master/next-hosts\?inline\=false
sudo sh -c "cat >> $OutHost" <<EOF

172.67.9.71 journals.aps.org
104.26.5.132 doi.org
66.22.61.221 iopscience.iop.org
104.20.229.70 orcid.org
172.64.146.247 www.researchgate.net
151.101.3.42 arxiv.org
EOF
sudo systemctl restart NetworkManager

Windows下修改hosts

  • 打开文本编辑器: 在管理员权限下打开你选择的文本编辑器。
  • 打开hosts文件: 在文本编辑器中,选择文件打开,找到的hosts文件
    C:\Windows\System32\drivers\etc\hosts
  • 编辑hosts文件: 在hosts文件的最后一行,添加你需要的域名和对应的IP地址。例如,你想将
    www.example.com指向本地的127.0.0.1,那么可以在hosts文件中添加以下内容:
    1
    127.0.0.1       www.example.com
    每个映射关系应该占据一行,IP地址和域名之间使用制表符或空格进行分隔。
  • 保存文件: 在编辑完成后,保存hosts文件。
  • 刷新DNS缓存
    • 打开命令提示符: 在开始菜单中搜索“命令提示符”,并以管理员权限打开。
    • 执行命令: 在命令提示符中输入以下命令,并按下回车键:
      1
      ipconfig/flushdns

参考文章

ArchLinux安装教程Sudo-ArchWiki中都默认建立了wheel组,并且赋予其sudo权限,这个操作就不是太安全了,因此在安装系统时您应当建立自己的组,而不是使用网上所统一使用的wheel,所以本文就来更正这个错误。

查看本机建立的组

1
2
3
groups
>
wheel yourname

建立自己的组并将当前帐号移到自己的组

1
2
sudo groupadd yourgrp
sudo usermod -aG yourgrp yourname

删除 wheel 组

1
sudo groupdel wheel

注意:删除wheel后,需要修改/etc/sudoers文件,将其中的wheel全部替换成yourgrp,这样您的yourgrp才能具备sudo的权限。

参考文章

每个人都知道 PID,究竟什么是 PID?为什么你想要 PID?你打算用 PID 做什么?你脑子里有同样的问题吗?如果是这样,你就找对地方了解这些细节了。

我们查询 PID 主要是用来杀死一个没有响应的程序,它类似于 Windows 任务管理器一样。 Linux GUI 也提供相同的功能,但 CLI 是执行 kill 操作的有效方法。

什么是进程 ID?

PID 代表进程标识号process identification,它在大多数操作系统内核(如 Linux、Unix、macOS 和 Windows)中使用。它是在操作系统中创建时自动分配给每个进程的唯一标识号。一个进程是一个正在运行的程序实例。

除了 init 进程外其他所有的进程 ID 每次都会改变,因为 init 始终是系统上的第一个进程,并且是所有其他进程的父进程。它的 PID 是 1。

PID 默认的最大值是 32768。可以在你的系统上运行 cat /proc/sys/kernel/pid_max 来验证。在 32 位系统上,32768 是最大值,但是我们可以在 64 位系统上将其设置为最大 222(约 4 百万)内的任何值。

你可能会问,为什么我们需要这么多的 PID?因为我们不能立即重用 PID,这就是为什么。另外为了防止可能的错误。

系统正在运行的进程的 PID 可以通过使用 pidofpgreppspstree 命令找到。

方法 1:使用 pidof 命令

pidof 用于查找正在运行的程序的进程 ID。它在标准输出上打印这些 id。为了演示,我们将在 Debian 9(stretch)系统中找出 Apache2 的进程 ID。

1
2
pidof apache2
3754 2594 2365 2364 2363 2362 2361

从上面的输出中,你可能会遇到难以识别进程 ID 的问题,因为它通过进程名称显示了所有的 PID(包括父进程和子进程)。因此,我们需要找出父 PID(PPID),这是我们要查找的。它可能是第一个数字。在本例中,它是 3754,并按降序排列。

方法 2:使用 pgrep 命令

pgrep 遍历当前正在运行的进程,并将符合选择条件的进程 ID 列到标准输出中。

1
2
3
4
5
6
7
8
pgrep apache2
2361
2362
2363
2364
2365
2594
3754

这也与上面的输出类似,但是它将结果从小到大排序,这清楚地说明父 PID 是最后一个。在本例中,它是 3754

注意: 如果你有多个进程的进程 ID,那么在使用 pidofpgrep 识别父进程 ID 时就可能不会很顺利。

方法 3:使用 pstree 命令

pstree 将运行的进程显示为一棵树。树的根是某个 pid,如果省略了 pid 参数,那么就是 init。如果在 pstree 命令中指定了用户名,则显示相应用户拥有的所有进程。

pstree 会将相同的分支放在方括号中,并添加重复计数的前缀来可视化地合并到一起。

1
2
3
4
5
6
7
pstree -p | grep "apache2"
|- apache2(3754) -|-apache2(2361)
| |-apache2(2362)
| |-apache2(2363)
| |-apache2(2364)
| |-apache2(2365)
| `-apache2(2594)

要单独获取父进程,请使用以下格式。

1
2
pstree -p | grep "apache2" | head -1
|- apache2(3754) -|-apache2(2361)

pstree 命令非常简单,因为它分别隔离了父进程和子进程,但这在使用 pidofpgrep 时命令不容易做到。

方法 4:使用 ps 命令

ps 显示活动进程的选择信息。它显示进程 ID(pid=PID)、与进程关联的终端(tname=TTY)、以 [DD-]hh:mm:ss 格式(time=TIME)显示的累计 CPU 时间、以及执行名(ucmd = CMD)。输出默认是未排序的。

1
2
3
4
5
6
7
8
9
ps aux | grep "apache2"
www-data 2361 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2362 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2363 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2364 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2365 0.0 0.4 302652 8400 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2594 0.0 0.4 302652 8400 ? S 06:55 0:00 /usr/sbin/apache2 -k start
root 3754 0.0 1.4 302580 29324 ? Ss Dec11 0:23 /usr/sbin/apache2 -k start
root 5648 0.0 0.0 12784 940 pts/0 S+ 21:32 0:00 grep apache2

从上面的输出中,我们可以根据进程的启动日期轻松地识别父进程 ID(PPID)。在此例中,apache2 启动于 Dec 11,它是父进程,其他的是子进程。apache2 的 PID 是 3754

引用