BNU-FZH

fengzhenhua@outlook.com


后续请大家继续关注博客:


  • 感谢这一年来GitLab的陪伴,并且为了在GitLab上面管理博客我还专门开始了脚本diary.sh. 但是由于GitLab要强制迁移到极狐GitLab, 并且后者是收费的,所以本博客不得不选择迁移回GitHub.
  • 2025年01月10日, 计划删除博客fengzhenhua-vip, 仅维护前两个。
阅读全文 »

ArchLinux是一款灵活、强大、可定制的Linux发行版,提供丰富的软件包和工具,支持滚动更新和多种桌面环境,拥有庞大的社区支持和方便的包管理器,适合各种用户需求和使用场景。Endeavour 是一个基于ArchLinux的轻量级和用户友好的发行版,预装了桌面环境和预配置的软件包,旨在提供一个无忧的ArchLinux体验。

阅读全文 »

今天升级syndns.sh脚本,升级为默认DNS 服务器为多个,当一个DNS服务器探测失败后使用下一个DNS服务器继续探测,从而大大提高了脚本的探测能力。在升级过程中,需要用到将默认DNS服务器数组作为参数传递到函数的问题,于是有了本文。

遍历所有参数: $@

1
2
3
4
#!/bin/bash
for para in "$@" ; do
echo $para
done

在上述例子中,使用for循环和$@遍历传递给脚本的所有参数,并逐个输出这些参数。其优点在于简洁,但也存在缺点,即无法指定输出哪一个参数。所以,对于不需要识别参数具体位置的情况,使用变量$@来遍历参数是个不错的方案。

参数的数量:$#

变量$#返回参数的数量,使用它配合$@可以指定输出确定位置的参数。例如

1
2
3
4
5
6
test(){
local paras=("$@")
for ((k = 0; k < $#; k++)); do
echo ${paras[$k]}
done
}

展开数组:${arr[@]}${arr[*]}

for的展开位置,可以使用上述两条命令,来逐一调用数组变量。例如

1
2
3
for ipc in ${SYN_IP[*]}; do
echo "$ipc"
done

数组作为参数传递给函数

需要注意的是,在将数组作为参数传递给函数时,参数形式只能使用"${Arr[*]}"才行。例如

1
SYN_DN2IP "${SYN_GITHUB[*]}" "$SYN_REC"

syndns.sh V2.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
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#! /bin/sh
#
# Program : syndns.sh
# Version : v2.1
# Date : 2024-12-28 12:10
# 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"
SYN_DNSIP=(8.8.8.8 119.29.29.29) # 默认DNS服务器
# Github 网站涉及的所有域名
SYN_GITHUB=(github.githubassets.com central.github.com desktop.githubusercontent.com \
assets-cdn.github.com camo.githubusercontent.com github.map.fastly.net github.global.ssl.fastly.net \
gist.github.com github.io github.com api.github.com raw.githubusercontent.com user-images.githubusercontent.com \
favicons.githubusercontent.com avatars5.githubusercontent.com avatars4.githubusercontent.com \
avatars3.githubusercontent.com avatars2.githubusercontent.com avatars1.githubusercontent.com \
avatars0.githubusercontent.com avatars.githubusercontent.com codeload.github.com \
github-cloud.s3.amazonaws.com github-com.s3.amazonaws.com \
github-production-release-asset-2e65be.s3.amazonaws.com \
github-production-user-asset-6210df.s3.amazonaws.com \
github-production-repository-file-5c1aeb.s3.amazonaws.com githubstatus.com github.community \
media.githubusercontent.com objects.githubusercontent.com raw.github.com copilot-proxy.githubusercontent.com)
#
# 参数1为域名数组,参数2 保存文件, 使用 SYN_DN2IP "${DOMAN[*]}" "outfile"
SYN_DN2IP(){
for hubweb in $1; do
unset SYN_IP
for ((k = 0; k < ${#SYN_DNSIP[@]}; k++)); do
SYN_IP="$(dig @${SYN_DNSIP[$k]} +short $hubweb)"
if [[ ! "$SYN_IP" =~ "#" ]]; then
k=${#SYN_DNSIP[@]}
fi
done
if [[ ! "$SYN_IP" =~ "#" ]]; then
for ipc in ${SYN_IP[*]}; do
echo "$ipc $hubweb" >> $2
done
fi
done
}
# 主程序
SYNDNS_PROCESS(){
cat $SYN_HOS |grep -v '^$'|grep -v '^#'|sort |uniq |sed -r 's/ * / /g' > $SYN_REC
# 需要专门对Github探测
SYN_DN2IP "${SYN_GITHUB[*]}" "$SYN_REC"
if [ -e $SYN_ADD ]; then
cat $SYN_ADD |grep '^[0-9]' |grep -v '^$'|grep -v '^#'|sort |uniq |sed -r 's/ * / /g' >> $SYN_REC
fi
cat $SYN_REC |grep '^[0-9]' |grep -v '^$'|grep -v '^#'|sort |uniq |sed -r 's/ * / /g' > $SYN_REC
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 restart dnsmasq.service, /bin/systemctl start dnsmasq.service
EOB
fi
elif [[ $1 =~ ".json" || $1 =~ ".dom" ]]; then
if [[ $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`)
elif [[ $1 =~ ".dom" ]]; then
Address=($(cat $1))
fi
if [ ! -e $SYN_ADD ]; then
touch $SYN_ADD
fi
SYN_DN2IP "${Address[*]}" "$SYN_ADD"
cat $SYN_ADD |grep '^[0-9]' |grep -v '^$'|grep -v '^#'|sort |uniq -u |sed -r 's/ * / /g' > $SYN_ADD
SYNDNS_PROCESS
fi
fi
# 默认执行主程序
SYNDNS_PROCESS

参考文章

近日决定升级一下路由器,最初从京东自营店购买的TP-BE5100, 但是发现收到的货是二手的,所以果断决定退货。经过对比,选择了口碑良好的华硕TUF-GAMING 小旋风 WiFi7 BE3600, 以过一下午的使用发现这款路由器确实值得购买。

AiDisk 共享USB 硬盘设置

TUF-GAMING 配置了一个 USB3.0 接口,通过这个接口我们可以设置自己的网络硬盘,这是一个相当实用的功能。下面是其设置方法:

  • 连接好路由,然后在游览器地址栏输入: http://www.asusrouter.com, 输入帐户名和密码进入到路由器管理页面。
  • 点击 外部网络(WAN)DDNS, 然后输入一个主机名,如果没有被占用,则可以成功开启,如果被占用则要更改新的主机名。
  • 点击 USB相关应用AiDisk, 然后根据向导设置就可以了。设置完成的样子:
    1
    2
    3
    4
    5
    您曾经设置过AiDisk向导,现在可参考以下信息来访问硬盘:
    Internet FTP address: ftp://yourhost.asuscomm.cn
    LAN FTP address: ftp://192.168.50.1
    若您需要更专业的文件共享设置,例如多组共享权限的规划,共享文件夹的修改,请至 这里设置。
    警告:AiDisk 已设置。若您再次设置,之前的帐号/密码与存取 权限都将重置。 欲添加更多帐号,选择 这里 以编辑帐户信息。

之后在文件管理器中输入上述 InternetLANftp地址,输入帐号名和密码就可以访问路由器U盘接口上连接的U盘了。

AiCloud 2.0 个人云应用

AiCloud提供了外网通过浏览器访问U盘接口上连接的U盘的功能。直接点击AiCloud 2.0 个人云2.0 应用根据提示设置就好。但是这里设置遇到了一些问题,比如

  • ASUS Router 在 HTTP 下外网可以连接路由器,HTTPS 下不可以。
  • AiCloud 内网情况下 Web 和 App 都可以登陆,外网情况下 Web 可以登陆,App 不能。
  • 参考文章:求助 AiCloud app外网登陆问题

应用下载

参考文章

在 neovim 中编辑 LaTeX 使用 vim-latex 插件是一个绝佳选择。然而,有时候写论文需要使用官方的 LaTeX的模板,但是不同出版社的模板设置多少有些不符合 LaTeX 规范,于是就会有字体等 Warning 信息出现,但是这些信息又不是 LaTeX 必须处理的,它们是可以忽略的。如果不忽略它们,每次编译 quicfix 窗口都会弹出提示,这极大的影响的写作体验,为此本文提供屏蔽这些信息的方法。

Neovim 中设置

~/.config/nvim/lua/plg/vim-latex.lua
1
2
3
4
5
6
7
8
9
-- 控制统计过程中的警告信息
vim.g['Tex_IgnoredWarnings'] = [[
LaTeX Font Warning:
LaTeX Warning:
Warning:
Overfull
]]
vim.g['Tex_IgnoreLevel'] = 4
vim.g['Tex_GotoError'] = 0

Vim 中设置

~/.vimrc
1
2
3
4
5
6
7
8
9
10
11
12
" 控制编译过程中的警告信息
let g:Tex_IgnoredWarnings =
\'Underfull'."\n".
\'Overfull'."\n".
\'specifier changed to'."\n".
\'You have requested'."\n".
\'Missing number, treated as zero.'."\n".
\'There were undefined references'."\n".
\'Citation %.%# undefined'."\n".
\"LaTeX hooks Warning"
let g:Tex_IgnoreLevel = 8
let g:Tex_GotoError = 0

注意:如果您想追加需要过滤的消息,请按上述标格式对应添加到Tex_IgnoredWarnings变量中即可,这样在nvimvim中输入\ll时,系统直接编译不再弹出quicfix窗口。

MbpsMB/s 转换计算器允许用户将转换为,这有助于理解不同单位的数据传输速率。

历史背景

Mbps(兆位每秒)和MB/s(兆字节每秒)这两个术语常用于计算和网络中描述数据传输速率。它们的区别在于测量单位:

1字节=8比特,这意味着从Mbps到MB/s的转换需要将Mbps值除以8。

此转换对于理解互联网速度、文件下载时间和网络设备的性能非常重要。例如,广告宣传的互联网速度为100 Mbps,转换为12.5 MB/s,这表明数据实际下载或上传的速度。

转换公式

Mbps转换为MB/s的公式很简单:

\[\begin{equation}\label{eq:translate} MB/s=\frac{Mbps}{8} \end{equation}\]

  • Mbps是以兆位每秒为单位的数据速率.
  • MB/s是以兆字节每秒为单位的数据速率.

在线转换

最近使用 lugit.sh 取代了 zugit.sh, 它可以把仓库建立在本地硬盘而不是像zugit.sh那样把仓库建立在U盘, 原因是U盘的质量太差了,如果不小心U盘 丢失了,那所有的源文件就丢了。综合考虑后,还是将仓库建立在台式机本地硬盘,进一步将仓库镜像到U盘, 可以实现不同电脑间的仓库离线同步。同时,对于保密性不太强的文件,完全可以直接使用网络仓库,如giteegitlab等。但是在同步的时候,需要修改一下远程仓库的默认分支,以实现每次本地仓库的同步都能只占一个分支,这样也可以节省远程仓库空间。

gitee 修改和删除分支

  • 打开gitee, 登录自己的帐号。
  • 打开要修改分支的仓库,点击左侧分支左边的小箭头→管理→右侧切换分支(一个向左向右的前头图标)
  • 如果要删除分支,则右侧切换分支下面的非默认分支是可以删除的。

gitlab 修改和删除分支

  • 打开 gitlab, 登录自己帐号。
  • 打开要修改分支的仓库,点击左侧SettingsRepositoryBranch defaults, 修改为新的分支即可。
  • 如果要删除分支,则点击仓库后,在右侧点击Branch,则非默认分支是可以删除的。

bash 支持一维数组(不支持多维数组),并且没有限定数组的大小。类似 C 语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0.

获取数组长度的标准方法

数组的个数称为数组长度,获取数组长度的标准方法为:

1
2
3
length=${#array_name[@]}   # 取得数组元素的个数
length=${#array_name[*]} # 同上
lengthn=${#array_name[n]} # 取得数组第n-1个元素的长度(字符串长度)

参考文章

在 Shell 脚本中经常需要添加前缀和后缀,如果使用循环的方式自然可以,但是从效率和规范上讲都不是最佳方式。本文记录标准添加前缀和后缀的方法。2024年12月14日星期六晴北京市

示例脚本

1
2
3
4
PREFIX="rajiv"
services=($( echo $* | tr -d '/' ))
echo "${services[@]/#/$PREFIX-}"
echo "${services[@]/%/-$PREFIX}"

命令解释

  • 第1行,定义前缀变量PREFIX.
  • 第2行,获取输入的所有变量,并使用tr -d去除字符/.
  • 第3行,在数组services的所有追加前缀$PREFIX-.
  • 第4行,在数组services的所有追加前缀-$PREFIX.
  • 第3,4行中的services[@]表示数组的所有元素,也可以用services[*]表示.

参考文章

在数学物理学中,格拉斯曼数(又称反交换数)是一种用于狄拉克场路径积分表示的数学架构。格拉斯曼数是以德国学者赫尔曼·格拉斯曼命名的。取任意两个格拉斯曼代数\(\theta\)\(\eta\), 则它们之间成反交换关系,即 \[\begin{equation} \theta\eta=-\eta\theta \label{eq:grassmann0} \end{equation}\] 同时格拉斯曼变量与一般的数\(x\)则为交换关系,即 \[\begin{equation} \theta x=x\theta \label{eq:grassmann1} \end{equation}\]

由于\(\theta^2=-\theta^2\), 所以有\(\theta^2=0\), 于是任意函数\(f(\theta)\)泰勒展开为 \[\begin{equation} f(\theta)=A+B\theta \label{eq:grassmann2} \end{equation}\] 既然函数\(f(\theta)\)是任意的,所以对于一个周期函数也必然成立,即 \[\begin{equation} \int f(\theta)d{\theta}=\int f(\theta+T)d{\theta} \label{eq:grassmann3} \end{equation}\] 把式\(\eqref{eq:grassmann2}\)代入到式\(\eqref{eq:grassmann3}\)可得 \[\begin{equation} \int A+B\theta d{\theta}=\int A+B\theta d{\theta}+BT\int 1 d{\theta} \label{eq:grassmann4} \end{equation}\] 由于对于任意的周期函数都成立,所以必然有 \[\begin{equation} \int 1d{\theta}=0 \label{eq:grassmann5} \end{equation}\] 对式\(\eqref{eq:grassmann2}\)积分得 \[\begin{equation} \int f(\theta)d{\theta}=B\int \theta d{\theta} \label{eq:grassmann6} \end{equation}\]\(\eqref{eq:grassmann6}\)中的积分不能对所有函数都是零,所认定义对\(\theta\)的积分为\(1\), 即 \[\begin{equation} \int \theta d{\theta}=1 \label{eq:grassmann7} \end{equation}\]