商店没办法打开,刷新 Store 应用的 cache、重置 Store 应用等都试过了,没有效果。
查询错误代码 0x80131500,发现与 TLS 有关。Winkey + R 运行 inetcpl.cpl,在高级中找到 TLS 1.2,打勾即可。
商店没办法打开,刷新 Store 应用的 cache、重置 Store 应用等都试过了,没有效果。
查询错误代码 0x80131500,发现与 TLS 有关。Winkey + R 运行 inetcpl.cpl,在高级中找到 TLS 1.2,打勾即可。
一般来说,如果没有进行过特殊配置的话(比如说我们用 debootstrap 安装的系统),其默认 locale 会是 POSIX,我们使用 locale 命令可以看到这个情况。
# locale LANG= LANGUAGE= LC_CTYPE="POSIX" LC_NUMERIC="POSIX" LC_TIME="POSIX" LC_COLLATE="POSIX" LC_MONETARY="POSIX" LC_MESSAGES="POSIX" LC_PAPER="POSIX" LC_NAME="POSIX" LC_ADDRESS="POSIX" LC_TELEPHONE="POSIX" LC_MEASUREMENT="POSIX" LC_IDENTIFICATION="POSIX" LC_ALL=
C 是系统默认的 locale,而 POSIX 是 C 的别名,因此这里看到的情况就是默认的 C Locale。它所指定的属性和行为由 ISO C 标准所指定。当我们新安装完一个系统时,默认的 locale 就是 C 或 POSIX。我们这里说的 C 其实就是 ASCII 编码。
但是我们同样也知道,标准的 ASCII 字符集中是不包含中文、日文等字符的,因此如果 POSIX 作为系统默认的 locale,那么会遇到在 SSH 下无法正确显示这些字符的问题,会直接按字节解析为 ASCII 转义字符,因此要想更正这个情况只有修改系统默认的 locale。
通过 locale -a 可以查看当前系统可用的所有 locale:
# locale -a C C.UTF-8 POSIX en_US.utf8
显然,en_US.utf8 是一个好选择。
下面贴过来一段对上文中提及的 LC_* 环境变量的接释:
从描述中可以看出,优先级级别:LC_ALL > LC_* > LANG
注意:定义这么多变量在某些情况下是很有用的,例如,当我需要一个能够输入中文的英文环境,我可以把 LC_CTYPE 设定成 zh_CN.GB18030,而其他所有的项都是 en_US.UTF-8。
如果我们要修改这个默认的变量,可以在自己的 ~/.bashrc 中进行 export,比如我加入了这两行:
export LANG=en_US.utf8 export LC_CTYPE=en_US.utf8
之后重新登录一下就可以正常显示 Unicode 字符了。
Ubuntu 的 netplan.io 实在是太烂了
Online 的 IPv6,之前写过一篇,是通过 /etc/network/interfaces 文件中的 pre-up 字段运行 dhclient 宣告 DUID,然而在 Ubuntu 18.04 中,ifupdown 换成了 netplan.io,原来的方法就不能用了。此外,dhclient 在每次运行的时候会清空当前 iface 上的 IPv6 地址,这个也给 netplan 造成了麻烦。在折腾之后有了一种解决办法:
需要写入如下文件:
/etc/dhcp/dhclient6.conf
interface "<iface>" { send dhcp6.client-id <DUID>; request; }
/etc/systemd/system/dhclient.service
[Unit] Description=dhclient for sending DUID IPv6 Wants=network.target Before=network.target [Service] Type=forking ExecStart=/sbin/dhclient -cf /etc/dhcp/dhclient6.conf -6 -P -v <iface> [Install] WantedBy=multi-user.target
/etc/systemd/system/dhclient-netplan.service
[Unit] Description=redo netplan apply after dhclient Wants=dhclient.service After=dhclient.service Before=network.target [Service] Type=oneshot ExecStart=/usr/sbin/netplan apply [Install] WantedBy=dhclient.service
该文件在 dhclient.service 改变状态之后执行,注意该 oneshot 不能使用 RemainAfterExit=True,不然在 restart dhclient 以后,不能再次执行 netplan apply。
/etc/netplan/01-netcfg.yaml
# This file describes the network interfaces available on your system # For more information, see netplan(5). network: version: 2 renderer: networkd ethernets: <iface>: dhcp4: yes dhcp6: no accept-ra: yes addresses: - <IPv6>/56
即可。
参考资料:
https://documentation.online.net/en/dedicated-server/network/network-configuration-with-netplan
https://documentation.online.net/en/dedicated-server/network/ipv6/prefix
https://askubuntu.com/questions/1031853/how-to-set-up-ipv6-with-netplan-on-ubuntu-18-04?rq=1
https://lafibre.info/scaleway/configurer-une-ipv6-online-net-sur-ubuntu-18-04/
https://unix.stackexchange.com/questions/219940/getting-a-service-started-automatically-when-another-gets-started
我无比怀念 Ubuntu 还在用 ifupdown 的年代,netplan.io 什么垃圾玩意。
起因是这样的,看阿里云打折,所以买了一个轻量 HK 来玩。阿里云的机器嘛,拿到手第一件事肯定是跑脚本重装系统,然后就默认装了最新的 Ubuntu 18.04。接下来发现,这机器没有 IPv6,于是就打算配置一下 HE Tunnelbroker,这时候问题就出现了,18.04 默认已经没有 ifupdown 而改用 netplan.io,HE 也没有提供 netplan 的样例配置。考虑到用新不用旧的原则(类比 systemd 和 Ubuntu upstart/update-rc.d),于是想折腾一下 netplan。
netplan 官网上宣称,它可以配置 6in4 Tunnel,还在官方示例(https://netplan.io/examples)最下面给出了对应的语法,然而在最新的 Ubuntu 内置版本上,tunnels 这个关键字根本不识别。查询 bug 发现在 https://bugs.launchpad.net/netplan/+bug/1799487 这里有人提到 netplan 无法使用 6in4 tunnel 的问题,也提出了一个使用 systemd-networkd 的解决方案。netplan 的 tunnel 支持根据这个 bug report 的说法,已经在一月初 commit,可能还没合并到软件包的版本里面吧。
阿里云的镜像,默认的网络配置是在 /etc/netplan/01-netcfg.yaml 中,默认是 DHCPv4 的方式获取内网 IP。我们先通过这里看到 v4 interface 的名称,比如 ens3。之后创建如下文件:
/etc/systemd/
[NetDev] Name=he-ipv6 Kind=sit MTUBytes=1480 [Tunnel] Local=<local IPv4 address> # should be the internal IPv4 address on Aliyun instead of the public IPv4 address Remote=<tunnel server IPv4 address> TTL=64
/etc/systemd/
[Match] Name=he-ipv6 [Network] Address=<Client IPv6 Address>/64 Gateway=<Server IPv6 Address>
/etc/systemd/
e.g. /etc/systemd/
[Network] Tunnel=he-ipv6
表示在默认的 v4 interface 上创建 tunnel。之后 systemctl restart systemd-networkd 即可
或者也可以使用 ip 命令在一个 systemd service 中完成添加:
[Unit] Description=he.net IPv6 tunnel After=network.target [Service] Type=oneshot RemainAfterExit=yes ExecStart=/sbin/ip tunnel add he-ipv6 mode sit remote <server IPv4 address> local <client IPv4 address> ttl 255 ExecStart=/sbin/ip link set he-ipv6 up mtu 1480 ExecStart=/sbin/ip addr add <client IPv6 address> dev he-ipv6 ExecStart=/sbin/ip -6 route add ::/0 dev he-ipv6 ExecStop=/sbin/ip -6 route del ::/0 dev he-ipv6 ExecStop=/sbin/ip link set he-ipv6 down ExecStop=/sbin/ip tunnel del he-ipv6 [Install] WantedBy=multi-user.target
在一些性能比较弱的机器上,比如 N2800,运行 qb 时可能会报错 ICE default IO error handler doing an exit()。
说实话这是一个比较莫名其妙的错误,ICE 是一个 X client 之间通信的协议,可能是 Qt 在后台有什么操作吧。StackOverflow 上对于这个错误的解决方法是删除 ~/.ICEauthority 文件,然后就好了。我猜可能是 qb 启动如果卡太久 GUI 出不来的话会把这个文件搞坏,然后再启动的时候读取这个文件就炸了,删除这个文件以后 Qt 可能会报一个 warning,authentication failure 之类的,这个不影响运行,而且 qb 也不会炸了。
这个文件在每次启动桌面时会自动生成,因此已加入 qb 自动重启脚本中的错误检测豪华套餐。
code –verbose 后报错:
[20447:0201/143519.959342:ERROR:browser_main_parts.cc(139)] X IO error received (X server probably went away)
这个似乎是一个 Electron 里面的 bug,一个可行的解决方案为:
# make a copy of the relevant library mkdir ~/lib cp /usr/lib/x86_64-linux-gnu/libxcb.so.1 ~/lib sed -i 's/BIG-REQUESTS/_IG-REQUESTS/' ~/lib/libxcb.so.1 # set the dynamic loader path to put your library first before executing VS Code LD_LIBRARY_PATH=$HOME/lib code
即修改一下 libxcb.so.1 之后再执行
对于 .desktop 文件启动的 VSCode(桌面的菜单项),将上述修改的 .so 文件复制到比如 /opt/code_lib 下,将 /usr/share/applications/code.desktop 中的 Exec 项修改为:
Exec=sh -c "env LD_LIBRARY_PATH\=/opt/code_lib /usr/share/code/code" %U
即可
仅作为记录,似乎这是个 Ubuntu 16.04 的 bug,在 18.04 中已经被修正
在 ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml
中找到这样一行:
<property name="<Super>Tab" type="string" value="switch_window_key"/>
<property name=”<Super>Tab” type=”string” value=”switch_window_key”/>
改成
<property name="<Super>Tab" type="empty"/>
<property name=”<Super>Tab” type=”empty”/>
就行了
这两天 KS-4 搞特价,4T 硬盘只要 9o,是公网保种机的绝佳配置,于是买买买。下机以后发现默认的系统模板沙雕了,/ 分区不能使用 SoftRaid0 方式挂载,虽然可以曲线救国把 /root 分一大块出来做 R0,但是我不喜欢这种分区方式,于是就想办法重装这个系统。
一开始我测试了 Airium 修改的 Vicer 重装脚本,这个脚本可以把 iKoula 的机器重装成 Raid0,然而不知道为什么一重装就 SSH 不通,遂放弃。在考察了 KS 的后台分区以后,发现 / 分区只能做成 Raid1,并且无法在上面配置 LVM,看来走官方模板的路子是走不通了。于是就剩下一个方法,在 Rescue 模式下手动安装系统。
KS 的机器在 Rescue 下安装系统主要有两个方法,一是使用 dd 安装 Windows,这不是我想要的,而且我也没有 Ubuntu 的 dd 镜像;二是下载系统镜像的 iso 安装包,使用 QEMU 将硬盘挂载以后在虚拟环境中完成安装。奈何 N2800 这个 CPU 过于古老,没有 VT-x 指令集,因而无法运行 QEMU,只好另辟蹊径。
在寻找如何在 Linux 下安装一个 ISO 文件的过程中,偶然发现了 Debian 系的 debootstrap 脚本,这个脚本可以在任何 Linux 环境下安装 Debian 系的 Linux。作为 Debian 的下游,Ubuntu 也有这个脚本,在一些文档的帮助下,我感觉这条路是可行的。
从一个比较 high-level 的角度来看,使用 debootstrap 安装系统需要如下几步:
接下来是详细的步骤
由于我要安装的是 Ubuntu 18.04,因此知道 OVH 的网络配置的最佳方法就是用官方模板装一遍,然后把配置弄出来。在安装之后,发现 OVH 并没使用 netplan,也没有使用之前的 ifupdown 文件,而是直接写了 systemd-networkd 的配置文件。需要备份的是这两个文件:
文件名可能不同,但是基本就是在这个目录下。对于老版本的系统,备份 /etc/network/interfaces。
理想的分区情况是这样的,两块盘 /dev/sda 和 /dev/sdb,分一个 512M 的区做 R1 挂载在 /boot,剩下的挂载在 /,swap 这里不考虑,装好了以后写一个文件作为 swap 是很方便的事情。
分区使用命令 fdisk,比如 fdisk /dev/sda,之后进入命令行交互环境。一个典型的配置情况如下:
root@rescue:/mnt# fdisk /dev/sda Welcome to fdisk (util-linux 2.25.2). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Device does not contain a recognized partition table. Created a new DOS disklabel with disk identifier 0xc1d78def. Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): p Partition number (1-4, default 1): 1 First sector (2048-3907029167, default 2048): Last sector, +sectors or +size{K,M,G,T,P} (2048-3907029167, default 3907029167): +512M Created a new partition 1 of type 'Linux' and of size 512 MiB. Command (m for help): n Partition type p primary (1 primary, 0 extended, 3 free) e extended (container for logical partitions) Select (default p): p Partition number (2-4, default 2): First sector (1050624-3907029167, default 1050624): Last sector, +sectors or +size{K,M,G,T,P} (1050624-3907029167, default 3907029167): Created a new partition 2 of type 'Linux' and of size 1.8 TiB.
按 n 增加分区,然后输入 p 作为 primary 分区,然后指定大小,默认是全部,因此第一个分区输入 +512M,第二个保持默认就好。
之后用 fdisk -l 可以看到当前的分区情况:
root@rescue:/mnt# fdisk -l /dev/sda Disk /dev/sda: 1.8 TiB, 2000398934016 bytes, 3907029168 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xc1d78def Device Boot Start End Sectors Size Id Type /dev/sda1 2048 1050623 1048576 512M 83 Linux /dev/sda2 1050624 3907029167 3905978544 1.8T 83 Linux
/dev/sdb 如法炮制即可。
使用命令 mdadm,先删除之前所有创建的 md,之后再创建新的,命令如下:
mdadm --stop /dev/mdX mdadm --remove /dev/mdX mdadm --create --verbose /dev/md0 --level=mirror --raid-devices=2 /dev/sda1 /dev/sdb1 mdadm --create --verbose /dev/md1 --level=stripe --raid-devices=2 /dev/sda2 /dev/sdb2
前两行多运行几遍直到所有的都被删除,之后创建 /dev/md0 RAID1 作为 /boot,/dev/md1 RAID0 作为 /。
使用 lsblk 可以看到当前的分区情况:
root@rescue:/mnt# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sdb 8:16 0 1.8T 0 disk ├─sdb2 8:18 0 1.8T 0 part │ └─md1 9:1 0 3.7T 0 raid0 └─sdb1 8:17 0 512M 0 part └─md0 9:0 0 511.4M 0 raid1 sda 8:0 0 1.8T 0 disk ├─sda2 8:2 0 1.8T 0 part │ └─md1 9:1 0 3.7T 0 raid0 └─sda1 8:1 0 512M 0 part └─md0 9:0 0 511.4M 0 raid1
然后格式化成 ext4 文件系统:
mkfs.ext4 /dev/md0 mkfs.ext4 /dev/md1
在这里下载 Ubuntu 的 debootstrap 脚本,应该会获得一个类似于 debootstrap_1.0.112ubuntu1_all.deb 的 deb 文件,使用 ar 释放后再解压至根目录下。ar 后会看到一个 data.tar.gz,释放到根目录下。
ar -x debootstrap_1.0.112ubuntu1_all.deb cd / zcat /pat/to/data.tar.gz|tar xv
接下来才是重头戏,挂载之前分好区的硬盘并安装系统。我们假定 /dev/md1 挂载在 /mnt/ubuntu 下,然后对 /mnt/ubuntu 运行 debootstrap 安装系统。
mkdir /mnt/ubuntu mount /dev/md1 /mnt/ubuntu debootstrap --arch amd64 bionic /mnt/ubuntu http://fr.archive.ubuntu.com/ubuntu/
debootstrap 的命令中,要求安装 amd64 架构的 Ubuntu bionic,也就是 18.04,系统在 /mnt/ubuntu 下,需要的包从 http://fr.archive.ubuntu.com/ubuntu/ 获得。
稍等一会儿, 看到 I: Base system installed successfully. 就安装完成了。
debootstrap 完成以后,在 /mnt/ubuntu 下就可以看到熟悉的 Linux 根目录结构了,然后我们做一些准备以方便 chroot 运行。
mount /dev/md0 /mnt/ubuntu/boot mount --bind /dev /mnt/ubuntu/dev mount --bind /dev/pts /mnt/ubuntu/dev/pts mount -t proc proc /mnt/ubuntu/proc mount -t sysfs sys /mnt/ubuntu/sys
第一行是将 /dev/md0 挂载在 /boot 下,这是和我们的分区意图相一致,2 3 两行是将当前系统的 /dev 映射进去,方便之后配置 fstab 文件,4 5 两行是将 proc 和 sysfs 挂载进去,方便配置时进行交互。
之后 chroot 进入新的环境:
LANG=C.UTF-8 chroot /mnt/ubuntu /bin/bash locale-gen en_US.UTF-8 export TERM=xterm-color
如果进去以后报错 “bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)” 则运行第二行,如果不报错就不用管了,第三行是为了 Terminal 好看点。
首先配置一下软件包的源,编辑 /etc/apt/sources.list 写入如下几行:
deb http://fr.archive.ubuntu.com/ubuntu bionic main restricted deb http://fr.archive.ubuntu.com/ubuntu bionic universe deb http://fr.archive.ubuntu.com/ubuntu bionic multiverse deb http://fr.archive.ubuntu.com/ubuntu bionic-backports main restricted universe multiverse deb http://security.ubuntu.com/ubuntu/ bionic-security main restricted deb http://security.ubuntu.com/ubuntu/ bionic-security universe deb http://security.ubuntu.com/ubuntu/ bionic-security multiverse
并且 apt update。完成后先安装 mdadm 和 lvm2,方便之后挂载。
apt-get install mdadm lvm2
编辑 /etc/fstab 写入挂载方式:
# file system mount point type options dump pass /dev/md0 /boot ext4 defaults 0 2 /dev/md1 / ext4 defaults 0 1
运行 mount -a 自动挂载,此时使用 df 命令应该可以看到正确的硬盘占用了。
运行 passwd 命令配置 root 用户密码,如果需要加用户,此时使用 adduser 即可。
之后安装内核和 OpenSSH Server:
apt-get install openssh-server linux-generic linux-tools-generic
正常情况下,在安装时会弹出 grub 的配置窗口,选择将 GRUB 安装在 /dev/sda 和 /dev/sdb,如果没有询问的话,安装完成以后运行如下两行:
grub-install /dev/sda grub-install /dev/sdb
之后写回最开始备份的网络配置文件,并且启动相关服务:
vi /etc/systemd/network/50-default.network vi /etc/systemd/network/50-public-interface.link systemctl enable systemd-networkd systemctl enable systemd-resolved
注意如果只有 root 用户的话,去 /etc/ssh/sshd_config 中修改 PermitRootLogin 为 yes,不然可能无法登录。
这时候就安装完成了,去 KS 后台用本地硬盘重启即可。在登录后记得配置 Public Key,然后将 PermitRootLogin 改为 PermitRootLogin prohibit-password。
最后在安装好的系统中使用 df 和 lsblk 命令查看分区情况:
root@rescue:~# df -h Filesystem Size Used Avail Use% Mounted on udev 1.9G 0 1.9G 0% /dev tmpfs 393M 676K 393M 1% /run /dev/md1 3.6T 1.3G 3.4T 1% / tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/md0 488M 73M 386M 16% /boot tmpfs 393M 0 393M 0% /run/user/0 root@rescue:~# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 1.8T 0 disk |-sda1 8:1 0 512M 0 part | `-md0 9:0 0 511.4M 0 raid1 /boot `-sda2 8:2 0 1.8T 0 part `-md1 9:1 0 3.7T 0 raid0 / sdb 8:16 0 1.8T 0 disk |-sdb1 8:17 0 512M 0 part | `-md0 9:0 0 511.4M 0 raid1 /boot `-sdb2 8:18 0 1.8T 0 part `-md1 9:1 0 3.7T 0 raid0 /
系统安装相关:
https://www.codejam.info/2015/12/installing-nixos-on-a-kimsufi.html
https://help.ubuntu.com/community/Installation/MinimalCD
https://www.pozzo-balbi.com/help/Remote_install_OS_-_Qemu
https://help.ubuntu.com/community/Installation/FromLinux
https://help.ubuntu.com/lts/installation-guide/powerpc/apds04.html
http://ports.ubuntu.com/ubuntu-ports/pool/main/d/debootstrap/
分区相关:
https://wiki.archlinux.org/index.php/Fdisk_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
https://raid.wiki.kernel.org/index.php/RAID_setup#Create_RAID_device
https://wiki.archlinux.org/index.php/Fstab_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
配置相关:
https://help.ubuntu.com/community/Installation/SoftwareRAID
https://wiki.archlinux.org/index.php/systemd-networkd#Basic_usage
https://unix.stackexchange.com/questions/158400/etc-shadow-how-to-generate-6-s-encrypted-password
这事情是这样的,我半个月前发现之前配置的 Syncthing 代理和 Nextcloud 页面的 Let’s Encrypt 证书都过期了。按道理讲,oneinstack 的一键包会添加一个 crontab 任务自动续签证书,但是就是没 work,手动执行 acme.sh 以后,发现是域名认证无法通过,请求 .well-known/acme-challenge
下的认证文件时返回 403 错误。
Nextcloud 使用了一键包中提供的 rewrite rule,Syncthing 是自己改的 nginx 配置文件,而同服务器上的 h5ai 却续签正常。在这种情况下,首先肯定是怀疑自己改错了。
在查看了 Syncthing 的 nginx 配置文件以后,发现默认将所有请求转发给 localhost 处理,那么问题就显而易见了,Syncthing 不知道那个 .well-known 是什么东西,自然返回错误,因此加上了一条 location 规则:
location /.well-known { }
嗯,可以续签了。
但是同样的方法在 Nextcloud 上却行不通,加入了这个规则以后,curl 仍然返回 403 错误。查看了 oneinstack 的 rewrite rule 以后发现,似乎本来就对这个目录做了处理。考虑到一堆正则看得头大,想着直接 override 掉好了,在查找了 location 的用法以后,加上了这么一行:
location ^~ /.well-known/acme-challenge { }
然后就能用了。
最后再转载一些对于 location 用法的解释:
location = / { # 精确匹配 / ,主机名后面不能带任何字符串 [ configuration A ] } location / { # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 # 但是正则和最长字符串会优先匹配 [ configuration B ] } location /documents/ { # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration C ] } location ~ /documents/Abc { # 匹配任何以 /documents/Abc 开头的地址,匹配符合以后,还要继续往下搜索 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration CC ] } location ^~ /images/ { # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。 [ configuration D ] } location ~* \.(gif|jpg|jpeg)$ { # 匹配所有以 gif,jpg或jpeg 结尾的请求 # 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则 [ configuration E ] } location /images/ { # 字符匹配到 /images/,继续往下,会发现 ^~ 存在 [ configuration F ] } location /images/abc { # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在 # F与G的放置顺序是没有关系的 [ configuration G ] } location ~ /images/abc/ { # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用 [ configuration H ] } location ~* /js/.*/\.js
已=开头表示精确匹配
如 A 中只匹配根目录结尾的请求,后面不能带任何字符串。
^~ 开头表示uri以某个常规字符串开头,不是正则匹配
~ 开头表示区分大小写的正则匹配;
~* 开头表示不区分大小写的正则匹配
/ 通用匹配, 如果没有其它匹配,任何请求都会匹配到
顺序 no优先级:
(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)上面的匹配结果
按照上面的location写法,以下的匹配示例成立:/ -> config A
精确完全匹配,即使/index.html也匹配不了
/downloads/download.html -> config B
匹配B以后,往下没有任何匹配,采用B
/images/1.gif -> configuration D
匹配到F,往下匹配到D,停止往下
/images/abc/def -> config D
最长匹配到G,往下匹配D,停止往下
你可以看到 任何以/images/开头的都会匹配到D并停止,FG写在这里是没有任何意义的,H是永远轮不到的,这里只是为了说明匹配顺序
/documents/document.html -> config C
匹配到C,往下没有任何匹配,采用C
/documents/1.jpg -> configuration E
匹配到C,往下正则匹配到E
/documents/Abc.jpg -> config CC
最长匹配到C,往下正则顺序匹配到CC,不会往下到E
因为 libtorrent 全是 bug,所以用了它的 qBittorrent 经常会莫名其妙出现一些错误,然后自己挂掉。虽然每次的 backtrace 都是在 libtorrent 里面出现的错误,但是同样用了 lt 的 Deluge 就一点都没有问题,所以估计这俩的代码都写得太差吧。
因此,写了一个简单的脚本去监控 qb 的运行状态,在它挂掉的时候自动重启,在漏内存的时候自动 kill 掉重开一个。
具体代码可以看 Github。默认行为是在 Xserver 存在的情况下启动 GUI 版的 qb,如果没有 Xserver 就启动 qbittorrent-nox,一分钟检测一次运行状态,挂了就重开。
如果在 VNC 下面使用 GUI 版的 qb,且想要随着桌面自动启动的话,需要在 ~/.config/autostart 下放置一个 desktop 文件
如果想看到一个 Terminal,并且监控一下重启的原因,用这个版本:
[Desktop Entry] Encoding=UTF-8 Version=0.9.4 Type=Application Name=qBittorrent-daemon Comment= Exec=bash -c '/usr/bin/python3 <path>/launch.py' OnlyShowIn=XFCE; StartupNotify=false Terminal=true Hidden=false
如果不需要看到那个 Terminal,用这个版本:
[Desktop Entry] Encoding=UTF-8 Version=0.9.4 Type=Application Name=qBittorrent-daemon Comment= Exec=/usr/bin/python3 <path>/launch.py OnlyShowIn=XFCE; StartupNotify=false Terminal=false Hidden=false