友邦拓 乌班图

During the first ten years of this HOWTO’s life, I reported that from a new user’s point of view, all Linux distributions are almost equivalent. But in 2006-2007, an actual best choice emerged: Ubuntu. While other distros have their own areas of strength, Ubuntu is far and away the most accessible to Linux newbies. Beware, though, of the hideous and nigh-unusable “Unity” desktop interface that Ubuntu introduced as a default a few years later; the Xubuntu or Kubuntu variants are better.

Eric Steven Raymond - How To Become A Hacker

学习 Linux 几点忠告

不要當“傳教士”

(這點有一個重大弊端:開放軟體沒有商業軟件那樣的宣傳,如果使用者都如此低調,用戶群不會大幅擴展。)

很多人在討論區不斷的引起的Linux對比Windows之類的討論,甚至爭的面紅耳赤,這是沒有必要的

這種爭論是浪費時間而沒有任何用處的。對,你花了一下午,用許多事實“捍衛”了Linux比Windows好這個說法。但是Windows的支持者並不會喜歡上Linux的,他們只是稍微退縮一下,然後找一些新的證據來跟你辯論。

世界上的人們都在利用Linux的研究最前沿的科學,我們還在這裡討論“要不要用Linux的這種無聊的問題,什麼時候才能趕上時代前進的步伐?

什麼叫做Window支持者,什麼叫做Linux的支持者?我們為什麼要支持某一個而反對另外一個?你不需要為 Linux的護法,不需要成為 Linux的支持者“或者”GNU的傳教士“ GNU / Linux的已經用事實向世界證明了它們的威力,已經被大多數人接受。你只需要安安靜靜享受的GNU / Linux的給你的樂趣和自由。

你需要關心的不是你的工具是什麼,而是你用它做了什麼。精通的Linux並不說明任何問題,因為它只是一個工具而已。如果你用的Windows能很好的完成你的任務,那你就沒有必要費時間去熟悉Linux操作系統。直到有一天你發現一項任務只有Linux操作系統才能完成的時候再換也不遲,因為你身邊的的Linux的愛好者一定會很樂意的幫助你。

如果你在使用Linux操作系統的過程中對它產生了感情,那麼你應該明白那些習慣於使用Windows的人也會對Windows產生依賴。類似的爭論還有很多:微軟 Office Word和TeX,Emacs和Vim,Wolfram Mathematica和Maple,侏儒,fvwm的和KDE的時候,狗派… …和冷靜地對自己說:“我不站在它們任何一邊。”儘管這有些不容易辦到。

各人的需要不同,生活的環境不同。對你來說好的東西,對別人來說不一定好,我們需要尊重別人的選擇。如果你當面說別人正在用的程序不好,沒有必要。

不要強迫自己

喜歡電腦的人總是有某些心理強迫傾向。有的人說:“鍵盤比滑鼠快。我不要用滑鼠。這樣才有高效率。”所以他在編輯器裡無論什麼時候總是用20W的,大於 10J這樣的命令到達目的點。他甚至覺得圖形界面是多餘的,乾脆都不裝 Xwindow。

全部用鍵盤看起來的確比讓手離開鍵盤去拿鼠標,再回來“快”多了,但是快的擊鍵頻率不等於工作的高效率,對你的健康更沒有什麼好處。這只能把你變成打鍵盤的機器。

當你正在檢查你的文章或者程序,思維正在隨著字符的含義流動,突然為 20W,大於 10J這樣的東西出現在你的腦子裡,是不是會打斷思路?不?那說明你當時思考的問題比較簡單,這些干擾還不會起到副作用。

其實很多人用電腦的時候,思想都受到某種教學的束縛,上面這個只是教多數種類中的一種。某些人創造了很多這種數學,用他的工作方式來要求別人,嘲笑方式跟他不一樣的人。比如有的人嘲笑其它人寫程序不按ç 8字符縮進,嘲笑別人在六裡用方向鍵,嘲笑別人不知道是什麼增值稅,嘲笑其它人用在Java,C#這種由地方選區回收內存語言 … …

你不用管各種各樣的教學,電腦只是你的工具,你想怎麼用就怎麼用。沒有人能夠約束你,沒有人可以嘲笑你的工作方式。電腦明天就不再是這個樣子,所以今天你不用完全了解它。你沒有必要知道別人創造的一切,因為你需要留點時間自己創造些東西。只要有樂趣!

當你下次修改文章的時候,不妨試試悠閒的用滑鼠在你眼睛看到的地方輕輕點一下。

如果你發現自己有類似的強迫症,建議去諮詢一下心理醫生。

不要“玩”Linux

Linux的很多人用的時候會感覺很迷茫,該用哪個發行版本呢?是不是我少裝了什麼?怎麼升級這麼快啊!怎麼這麼不穩定!每當遇到新的軟件他就想試用,每當新的版本出現,他就更新,然後用鼠標在新的菜單裡選擇從來沒見過的程序來用用。

其實你是為了玩Linux而使用Linux操作系統的,而沒有找到正確的理由來利用Linux操作系統。你首先要明確用電腦的目的,你用它是為了解決你的實際問題,而不是為了學習安裝操作系統,不是為了測試哪個版本好用,不是為了“趕上潮流,更不是因為你硬盤太大了,你想多佔點空間。

如果你啟動了電腦之後不知道應該幹什麼,那麼最好先不要用電腦,因為你可能有更重要的事情需要做。這沒什麼說的。

不用挑剔發行版本

很多人剛開始用linux的時候,總是在懷疑別的發行版本是否比自己正在用的這個好,總是懷疑自己以後什麼時候會失去支持,不得不換用別的發行。所以很多人今天是紅帽,明天又換成了Debian的,一會兒又是巴布亞… …甚至有的人在一台機器上裝了兩個版本的Linux操作系統,然後比較哪一個好。

其實你完全沒有必要這樣做,任何發行,只要你熟悉了,你在上面的工作方式幾乎不會受到任何影響。我以前一直用的紅帽,當我有一天在我的一台新機器上安裝Debian時,我發現使用紅帽的經驗完全沒有浪費。我用了一個下午就配置好了Debian,使它服服貼貼的聽我的話,就跟沒有換發行版本一樣。

Debian,拓林思,SuSE,紅帽,Gentoo… …任何一個版本都是不錯的。很多人認為自己攢一個 LFS的是高水平黑客的象徵,但是不是每個人都有精力去了解所有細節。

不要盲目升級

不知道這是心理作用還是什麼,有的人看到比較大的版本號,就會很想換成那個。很多人的Redhat的本來配置的很舒服了,可是一旦Redhat的發行新的版本,他們就會盡快下載過來,然後選擇升級安裝。結果很多時候把自己原來修改得很好的配置文件給沖掉了。新的軟件又帶來了新的問題,比如有一次我的rxvt的就升級到2.7.8跟miniChinput衝突了,升級到Redhat的8.0,xmms的發現居然缺省不能放了MP3播放,XFree86的是i810的模塊在啟動上有新的漏洞,Mozilla中,會導致突然退出。

如果你已經配置好了一切,千萬別再整體升級了,這會浪費你很多很多時間的,不值得。有句話說得好:“如果沒有打破,不解決它。”如果你的程序能夠完成你需要做的事情,你何必升級呢????

是的,不論是從論壇還是其他的地方反映出來的大部分都是這個問題,要么比较SUSE和Ubuntu的好,要么比Ubuntu或者Mandriva的好等等的言論。很多人還是把Linux操作系統看成了一個表面的東西。並沒有塌下心來學習 Linux系統。

不要配置你不需要的東西

如果你只想做一個像我這樣的普通用戶,主要目的是用的Linux來完成自己的科研任務和日常工作,那就可以不用系統管理員或者網絡管理員的標準來要求自己,因為當一個系統和網絡管理員確實很辛苦。普通用戶學習那些不經常用到的複雜的維護系統的工具,其實是浪費時間,學了不用是會很快忘記的!

我不是一個合格的網絡管理員,我的服務器都只設置了我自己需要的功能,設置好ssh連接的ftp已經足夠了,那樣可以省去我很多麻煩。我從來不過度考慮“安全,因為 Linux操作系統缺省已經很安全了。我沒有磁帶機,就不用管tar的那些稀奇古怪的參數了,czf,xzf,ztf已經可以滿足我所有的需要。桑達,awk的,…我也只會幾種常用的命令行。

不要習慣的使用根帳號。在需要的時候才用!

這是很多剛接觸的UNIX類操作系統的人常見的現象,他們不喜歡在管理系統的時候才用,而是一直用根帳號幹所有事情,配置系統,安裝程序,瀏覽網頁,玩遊戲,編程 … …

結果有一天,他不小心在某個系統目錄使用了del * …後果不堪設想 … …

不要用商業的眼光來看待Linux

Linux不是商業軟件,所以不要用要求Solaris操作系統,視窗那樣的眼光來看 Linux操作系統。自由軟件的作者們從來不拉攏用戶,他們對用戶不負有任何責任。實際上在自由軟件的世界裡,開發者“和”用戶“並沒有明確的界限,大家是朋友。

自由軟件很可能只是滿足作者和他的朋友的需要,甚至是為了好玩而創造的。自由軟件不是完美的,自由軟件承認自己有缺點,它不會自吹自擂,蒙蔽“用戶”的耳目。這種對作者責任的解脫激發了作者的創造力,他們不用過分考慮“向上兼容,他們往往比背上重重包袱的商業軟件結構更合理,技術更先進。

所以當你用某個自由軟件遇到困難的時候,不應該埋怨軟件的作者,因為他們對你並沒有義務。你不應該把自己當成一個挑剔的顧客,而要把自己作為這個軟件的顧問和一個和藹的建議者,這樣你才能理解作者寫這個程序時的快樂,在遇到問題時向作者反映,幫助他完善這個軟件,成為一個快樂的參與者。就像你的哥哥送你一個他用舊了的自行車,你應該珍惜這份友情,而不要在車壞了,或者騎車摔了一跤的時候大罵你的哥哥。如果你真的不能使用這種合作的心態,那麼最好不要使用這個軟件。

這是一種先進的文化,它包含了互相合作,科學創新的精神。理解這一點不是很容易,很多人往往是因為不能理解這種文化而離開自由軟件。這對於作者來說並沒有什麼損失。

幹你的正事去

很多人跟我說,你的網頁浪費我好多時間來配置這配置那,一會兒是fvwm的,一會兒是Mutt中… …

嗯… …那些東西都是我有空的時候一點一點積累的,如果你想一次性搞定所有那些東西,恐怕得花你幾個星期甚至幾個月的時間!並不是一定要搞定所有這些東西你才能正常工作的。除非你真的非得利用某個程序,或者你閒著沒事,否則你可以不管這些東西。

上面幾條僅供參考

以上只是個人意見,不一定適合所有人。取捨由你了!

Settings

gnome-control-center

DNS

最近经常出现 Firefox 可以打开 GitHub 网站,但是命令行 Git 无法拉取/推送代码的情况。甚至开了 VPN 也不行。运行 ping 命令发现 github.com 被解析到了 127.0.0.1,这是 DNS 被劫持了。是谁搞的鬼,相信你一定懂得。

为啥 Firefox 可以打开 GitHub

最新的 Firefox 桌面版默认启用了 DoH(DNS over HTTPS),通过向特定的服务器发送 HTTPS 请求获取域名的 IP 地址。这就绕过了电信/联通/移动等提供的有毒 DNS 服务器。因为 DoH 采用 HTTPS 协议,不容易被劫持。另外国内用 Firefox 的很少,这个技术并不普及,所以暂时没有被老大哥盯上。

但是很可惜,DoH 目前无法在 Linux 系统层面支持,运行命令行仍然是使用 ISP 提供的 DNS 服务器。电信/联通/移动经常抽风,甚至某些路由器都会给你下毒,让你打不开网页或者直接跳到某网址导航。

为啥开了 VPN 也不行

因为通常是先连接本地网络,这时候已经从 ISP 获取了一个 DNS 服务器。再连接 VPN,(以 OpenVPN 为例)仍然是用的这个 DNS 服务器。

某些商业 VPN 客户端是会在连接上 VPN 之后自动更换 DNS 服务器的。但是 Linux 自带的网络管理是没这个能力的。

因此,如果你只用 Linux 自带的网络管理,最好的解决方法依然是手动设置一个可靠的 DNS 服务器。

DNS 服务器哪家强

如果你去网上搜,很多老的文章会推荐这两个:

  1. Google 的 8.8.8.8
  2. Cloudflare 的 1.1.1.1

这两个 DNS 还是能用的,但是在有些地方不太稳定,甚至直接连不上。

目前还是推荐国内正规企业提供的 DNS 服务器:

  1. DNSPod/腾讯云 119.29.29.29
  2. 阿里云 223.5.5.5

并不能保证腾讯和阿里的 DNS 百分之百可靠,但是比电信/联通/移动好太多。起码 GitHub 是可以正常解析的。

如何设置 DNS

这里就只介绍普通桌面用户用 NetworkManager 和 KDE 的用法。GNOME 基本类似。用 Wicked 的都是技术大佬,相信也不用看下面这些了。

  1. 从系统托盘网络图标右击,打开“网络设置”。
  2. 选择你的有线或者 WiFi 链接,进行编辑。
  3. 切换到 IPv4 标签页。
  4. 将“方法”从“自动”改成“自动(仅网络地址)”。
  5. 将“DNS服务器”改成“119.29.29.29”。
  6. 点“应用”并关闭“网络设置”窗口。
  7. 点击系统托盘的网络图标,打开网络列表,断开并重新链接。

注意,如果需要频繁更换不同的 WiFi 链接,则需要对不同的 WiFi 配置添加自己的 DNS 服务器。

如果是自己家的网络,可以在路由器上配置,方法和上面类似,都是配置 IPv4 方法和 DNS 服务器。(注意,路由器的 WAN 互联网和 LAN 局域网设置都要配一下)这样家里的设备就不用单独配置了。

CLI

# 显示当前网络连接
$ nmcli connection show
# 修改当前网络连接对应的DNS服务器,这里的网络连接可以用名称或者UUID来标识
$ nmcli con mod ens160 ipv4.dns "8.8.4.4 8.8.8.8"
# 配置生效
$ nmcli con up ens160

或者

# Config File
$ vi /etc/netplan/01-network-manager-all.yaml
network:
  version: 2
  renderer: NetworkManager
  ethernets:
    ens3:
      dhcp4: no
      addresses:
        - 192.168.100.199/24
      gateway4: 192.168.100.1
      nameservers:
        address: [8.8.4.4, 8.8.8.8]
  wifis:
    ...
# Apply the changes you made in the config file
$ sudo netplan apply
# To check if the system successfully applied the changes
$ systemd-resolve --status | grep 'DNS Servers' -A2
         DNS Servers: 8.8.4.4
                      8.8.8.8        

注意:您系统上的文件可能缺少整个以太网或 wifi 部分。 在这种情况下,添加缺少的行,确保遵守示例中提供的缩进。

Testing the Domain Name Resolution Speed

time dig @8.8.4.4

清空 DNS 缓存

因为 DNS 记录是有本地缓存的,即使你更换了 DNS 服务器,依然会优先从缓存里取 IP 地址。所以更换 DNS 之后,需要清空 DNS 缓存。

这是一个比较头疼的问题,因为各家 Linux 发行版用来管理 DNS 的方式不一样,清空 DNS 缓存的方法也不一样。最通用的方法:重启系统。

如果不想重启系统,那么可以参考这篇How to flush the DNS cache on Linux 。我大概总结一下,就是逐个试下面的命令:

sudo systemd-resolve --flush-caches
sudo systemctl restart nscd
sudo systemctl restart named

如果没有用的话,还是重启系统吧。

测试 DNS 解析

首先用 nslookup 测试一下 DNS 服务器是否能解析,如果解析出来的 Server 是你之前配的地址,Address 不是 127.0.0.1 或者 0.0.0.0 这种,应该就是好的。

$ nslookup github.com
Server:         119.29.29.29
Address:        119.29.29.29##53

Non-authoritative answer:
Name:   github.com
Address: 20.205.243.166

但是 nslookup 能解析,并不意味着就能连上。实际连接还要看 ping 命令。注意 github.com 并不回应 ping 请求,也就是数据包都会 lost,这是正常的。只要 ping 能解析到 IP 地址就行了。

$ ping github.com
PING github.com (20.205.243.166) 56(84) 字节的数据。
^C
--- github.com ping 统计 ---
已发送 3 个包, 已接收 0 个包, 100% packet loss, time 2049ms

如果 ping 没问题,最后再试一下 git pull 命令。如果不能访问,则需要试试 VPN 了。

Others

  • Bluetooth: OFF
  • Formats: United States
  • Night Light: ON
  • Blank screen: 10
  • Touchpad: OFF
  • Fractional Scaling

SoftWare&Updates

software-properties-gtk or software-properties-kde (Kubuntu) and update-manager (Software Updator)

  • Ubuntu Software 栏 Download from 选择 USTC MIRRORS。也可以在 Official Archive Mirrors for Ubuntu 中选择。

  • Other Software 栏下开启 Canonical Partner Repositories (The partner repositories offer access to proprietary and closed-source software)。

  • Ubuntu 自动下载并安装对你的系统至关重要的安全更新。而这个自动更新经常导致你“无法锁定管理目录”错误。在 Updates 栏下选择

    • For other packages, subscribe to: All updates
    • Automatically check for updates: Every two weeks
    • When there are security updates: Download and Install automatically
    • When there are other updates: Display immediately
    • Notify me of a new Ubuntu version: For long-term support versions
  • 更新系统:

    sudo apt update
    sudo apt upgrade
    sudo apt autoremove
    
  • Livepatch: 更新内核不需要 Reboot required 了

    sudo ua attach <subscription>
    

Ubuntu Software & Update 卡在 cache refresh

通过 apt update 可以看见是 Connecting to security.ubuntu.com Failed,解决办法是更改 /etc/hosts 文件添加其 IP,可通过 EASYCOUNTER 查找:

## security.ubuntu.com
91.189.88.142 security.ubuntu.com
91.189.88.152 security.ubuntu.com
91.189.91.38 security.ubuntu.com
91.189.91.39 security.ubuntu.com
## archive.canonical.com
91.189.92.150 archive.canonical.com
91.189.92.191 archive.canonical.com
91.189.91.15 archive.canonical.com
## downloads.sourceforge.net
216.105.38.13 downloads.sourceforge.net

ubuntu下如何获取源码包和源码

  • 在 Software & Updates 中选中 Source code,不要 Reload,因为很慢,在命令行中 update。或者在软件源配置文件 /etc/apt/sources.list 中添加 deb-src 项。

  • 获取 xxx 源码包的详细信息

    sudo apt-cache showsrc xxx
    
  • 获取源码包,并将源码包解压到同名目录

    sudo apt-get source  xxx 
    

Upgrade Ubuntu version

  • 打开 Software Updater 更新软件
  • 打开 Software & Updates 选择 Updates 栏,在 Notify me of a new Ubuntu Version 中选择 For any new version 。
  • 打开 Software Updater 更新到新 Ubuntu 版本。
  • 使用 lsb_release -a 确认 Ubuntu 版本。

Input Method Editor

首先在 Language Support (gnome-language-selector,注意不要在终端中运行这个命令,因为环境不一样) 中下载语言包。

里面的选择输入法实质是 im-config 这个包。

IBus

ubuntu libpinyin 输入法支持云拼音,只需要开启就可以了。

Emoji input

IBus supports the input of emoji icons. Type Ctrl+. or Ctrl+; and you will see the input prompt change to an underlined e character. You can then type the symbol or name of the emoji you want (e.g. :) or face) and press Space to render it. If you are satisfied with the result press Enter to submit it and exit emoji input mode, or press Space for a second time to open a dialog where you can further customize your desired emoji.

See ibus-emoji(7) for more information.

Unicode input

IBus supports the input of complex Unicode characters. Type Ctrl+Shift+u and you will see the input prompt change to an underlined u character. You can then type the code of the Unicode character you want and press Space or Enter to render and submit it.

  • 間隔號「·」U+00B7

搜狗细胞词库

hslinuxextra下载sougou-phrases-full.7z

经过与ibus开发者协商,ibus-pinyin的词库查找规则做了一些更改,只要在词库目录(就是有一个.db文件的那个目录,一般是/usr/share/ibus-libpinyin/db/目录)把新词库复制过来并改名为local.db就可以使用了,如果感觉词库不好,直接删除掉local.db,就可以让ibus使用原来的词库。

覆盖以后,你把ibus重启一下ibus-daemon -d -x -r,如果你能打出下面的这个词组,说明生效了:

弗雷德霍姆行列式

这个词库,基于ibus原有的android词库文件,另外增加了搜狗的细胞词库。

Fcitx 4

在Ubuntu Wayland 桌面中使用fictx管理中文输入法

sudo apt install fcitx -y

设置 fcitx:

  • 在 Language Support 中选择 fcitx,全局应用,并恢复 ibus 自定义切换语言快捷键设置。

  • (可选)wayland桌面默认不读取/etc/profile中的环境变量,而是从/etc/environment文件中读取,这是导致fcitx不能正常工作的原因。

    $ sudo vim /etc/environment
    INPUT_METHOD=fcitx
    GTK_IM_MODULE=fcitx
    QT_IM_MODULE=fcitx
    XMODIFIERS=@im=fcitx
    

输入法框架:

其他:

  • 百度输入法不能安装用于更换皮肤的 fcitx-ui-qimpanel,否则乱码。需要手动安装 fcitx-libs,否则开机不自动启动。
  • 在 fcitx 与 sogoupinyin 安装完之后,需要重启才能使用。

皮肤:

Fcitx 5

安装

配置工具 KDE 下使用 kde-config-fcitx5, Gnome 下使用 fcitx5-config-qt

20.04 (20220122) 官方仓库里没有 Gnome 的配置工具 kcm-fcitx5(内含 fcitx5-config-qt),因此通过 ppa:zhsj/fcitx5 来安装

sudo add-apt-repository ppa:zhsj/fcitx5
sudo apt-get update
sudo apt install fcitx5 fcitx5-chinese-addons

或者也可以通过**通过 flatpak 安装**。

安装后在 Ubuntu 在 Language Support 里修改输入法系统为 fcitx5,记得点击 Apply System-Wide。

安装报如下错

E: Failed to fetch http://103.95.217.6/ppa.launchpad.net/zhsj/fcitx5/ubuntu/pool/main/f/fcitx5-chinese-addons/fcitx5-module-cloudpinyin_5.0.4-1~ubuntu20.04.1~ppa1_amd64.deb  503  Service Unavailable [IP: 103.95.217.6 80]
E: Aborting install.

可以在浏览器中打开链接直接下载。

肥猫百万大词库

Download latest version of “zhwiki.dict” from https://github.com/felixonmars/fcitx5-pinyin-zhwiki/releases

Copy into ~/.local/share/fcitx5/pinyin/dictionaries/ (create the folder if it does not exist)

可以在设置中看到是否启用,或者输入 “jinjinjin” 会出现 “鑫”。

fcitx5 皮肤绘制简易教程

Tips

通过 Fcitx5 输入特殊字符

将光标定位到任意一个输入框内,然后按下 Ctrl + Alt + Shift + U,然后输入 circle one,您将会看到多种形式的 。alpha, beta, sigma 等同理。

emoji表情

fcitx输入法自带的表情名都是英文的,而且以两个:包含住的,例如🌹(玫瑰rose),按下;后,输入🌹即可打出玫瑰的图标(更多内置图标名字见 Fcitx Configuration => Addons => Quick Phrase => Editor => emoji-eac)。

RIME

RIME/中州韵输入法引擎(Rime Input Method Engine),是一个跨平台的可高度定制的输入法算法框架。基于这个算法框架,Rime 開發者與其他開源社區的參與者在 Windows、macOS、Linux、Android 等平臺上創造了不同的輸入法前端實現。每个平台都有各自的名称:

  • 【中州韵】 ibus_rime → Linux
  • 【小狼毫】 Weasel → Windows
  • 【鼠须管】 Squirrel → Mac OS X

在 Linux 下有两大主要的输入法支持框架:fcitx 和 IBus。

  • fcitx 是 Free Chinese Input Toy for X 的简称。
  • IBus 是 Intelligent Input Bus 的简称。

Rime 二者都支持,有 ibus rime 和 fcitx-rime 两个版本。值得注意的是,基于 Fcitx 输入法框架的 fcitx-rime 是第三方软件,由 Fcitx 团队开发和维护。

# ibus
$ sudo apt install ibus-rime
# fcitx4
$ sudo apt install fcitx-rime
# fcitx5〔方案選單〕 
$ sudo apt install fcitx5-rime

按组合键 Ctrl+`F4 键唤出输入方案选单,由此调整 Rime 输入〔方案選單〕 法最常用的选项。您可通过方案选单切换已经安装的输入方案。

更多中州韵输入法配置,请阅读晦涩的官方文档:

必知必会

  • 输入法代号:ibus_rime
  • ibus 用户资料夹: ~/.config/ibus/rime/
  • fcitx 用户资料夹:~/.config/fcitx/rime
  • fcitx5 用户资料夹:~/.local/share/fcitx5/rime
  • 共享资料夹: /usr/share/rime-data/

共享资料夹包含预设输入方案的源文件。 这些文件属于 Rime 所发行软件的一部份,在访问权限控制较严格的系统上对用户是只读的,因此谢绝软件版本更新以外的任何修改—— 一旦用户修改这里的文件,很可能影响后续的软件升级或在升级时丢失数据。

在「部署 Rime」操作时,将用到这里的输入方案源文件、并结合用户定制的内容来编译预设输入方案。

「用户资料夹」数据说明

用户资料夹则包含为用户准备的内容,如

  • 〔全局設定〕 default.yaml
  • 〔發行版設定〕 ibus_rime.yaml:定制外观一般情况下会在 <发行版>.custom.yaml 文件中进行配置,Linux 下就是 ibus_rime.custom.yaml,macOS 下是 squirrel.custom.yaml,windows 下就是 weasel.custom.yaml
  • 〔預設輸入方案副本〕 <方案标识>.schema.yaml ibus_rime.schema.yaml
  • ※〔安裝信息〕 installation.yaml
  • ※〔用戶狀態信息〕 user.yaml

编译输入方案所产出的二进制文件:

  • 〔Rime 棱鏡〕 <方案标识>.prism.bin
  • 〔Rime 固態詞典〕 <词典名>.table.bin:由系统文本词库(一般以xxx.dict.yaml结尾)通过「重新部署/deploy」生成的固态词典(一般以xxx.table.bin结尾),这部份词库因为在输入过程是固定不変的,所以存在用大量的词彚,也不允许用戸来直接删除。
  • 〔Rime 反查詞典〕 <词典名>.reverse.bin

记录用户写作习惯的文件:

  • ※〔用戶詞典〕 <词典名>.userdb.kct:记录我们用戸输入习惯的用戸词典(一般以xxx.userdb.kct)结尾。这部份词库的词彚,正常情况下是由用戸输入的时候随时生成的;其词彚可以动态调整,数量理论上来说不会特别多,也允许用戸自行删除(shift+delete)。
  • ※〔用戶詞典快照〕 <词典名>.userdb.txt<词典名>.userdb.kct.snapshot 見於同步文件夾

以及用户自己设定的:

  • ※〔用戶對全局設定的定製信息〕 default.custom.yaml
  • ※〔用戶對預設輸入方案的定製信息〕 <方案标识>.custom.yaml
  • ※〔用戶自製輸入方案〕及配套的詞典源文件

注:以上标有 ※ 号的文件,包含用户资料,您在清理文件时要注意备份!

关于配置的位置问题

要更改輸入方案裏面的選項,給輸入方案打補靪;

要更改全局選項,給 default.yaml 打補靪;

要更改「小狼毫」專屬的選項,如界面樣式,給 weasel.yaml 打補靪。

總地來說規則是:要修改的配置項在 x(.schema).yaml 裏,就編輯 x.custom.yaml 打補靪。

定制

定制指南

当用户需要对 Rime 中的各种设定做小幅的调节,最直接、但不完全正确的做法是:编辑「共享资料夹」中那些 .yaml 文档(/usr/share/rime-data/ )。

这种方法有很大缺陷:

  • 当 Rime 软件升级时,也会升级各种设定档、预设输入方案。用户编辑过的文档会被覆盖为更高版本,所做调整也便丢失了。
  • 软件升级后,你不能将备份文件直接覆盖升级后的文件。这将失去本次升级所新增和修复的功能。唯一的方法是,重新编辑升级后的文件。

因此,对于随 Rime 发行的设定档及预设输入方案,推荐的定制方法是:

在「用户资料夹」下创建 .yaml 定制文档;比如

  • default.yaml 的定制文件名为 default.custom.yaml
  • luna_pinyin 的定制文件名为 luna_pinyin.custom.yaml
  • luna_pinyin_simp 的定制文件名为 luna_pinyin_simp.custom.yaml
  • symbols.yaml 的定制文件名为 symbols.custom.yaml

规范为在文件名主体(ID)和 .yaml 之间增加次级扩展名 .custom。定制文档的书写格式为:

patch:
  "一级设定项/二级设定项/三级设定项": 新的设定值
  "另一个设定项": 新的设定值
  "再一个设定项": 新的设定值
  "含列表的设定项/@n": 列表第n个元素新的设定值,从0开始计数
  "含列表的设定项/@last": 列表最后一个元素新的设定值
  "含列表的设定项/@before 0": 在列表第一个元素之前插入新的设定值(不建议在补丁中使用)
  "含列表的设定项/@after last": 在列表  "一级设定项/二级设定项/三级设定项": 新的设定值最后一个元素之后插入新的设定值(不建议在补丁中使用)
  "含列表的设定项/@next": 在列表最后一个元素之后插入新的设定值(不建议在补丁中使用)

就是这样:patch 定义了一组「补丁」,以源文件中的设定为基础,写入新的设定项、或以新的设定值取代现有设定项的值。

每次修改配置文件,你需要重新部署来生效。

重新部署的操作方法

  • 点击输入法的程序指示器,选择「部署」

  • 点击输入法状态栏上的 ⟲ (Deploy) 按钮。如果找不到状态栏,在终端输入以下命令,可触发自动部署:

    # ibus
    $ rm ~/.config/ibus/rime/default.yaml; ibus-daemon -drx
    
定制每页候选数

Rime 中,默认每页至多显示 5 个候选项,而允许的范围是 1〜9(个别 Rime 发行版可支持 10 个候选)。

设定每页候选个数的默认值为 9,在用户目录建立定制文档 :

$ vi ~/.config/ibus/rime/default.custom.yaml
patch:
  "menu/page_size": 9

重新部署即可生效。

注意! 如果 default.custom.yaml 里面已经有其他设定内容,只要以相同的缩进方式添加 patch: 以下的部分,不可重复 patch: 这一行。

定制方案选单
$ vi ~/.config/ibus/rime/default.custom.yaml
patch:
# 對於列表類型,現在無有辦法指定如何添加、消除或單一修改某項,於是要在定製檔中將整個列表替換!
  schema_list:  
    - schema: luna_pinyin
    - schema: cangjie5
    - schema: luna_pinyin_fluency
    - schema: luna_pinyin_simp
    # 這樣就啓用了未曾有過的高級輸入方案!其實這麼好的方案應該排在最前面哈。
    - schema: my_coolest_ever_schema  

调整方案候选顺序,增加输入法方案,或者通过 # 注释内容将不用的方案移除候选菜单。

重新部署生效。

定制字体字号

GNOME 桌面可以使用扩展 IBus Tweaker

$ vi ~/.config/fcitx/rime/default.custom.yaml
patch:
  # 字體名稱,從記事本等處的系統字體對話框裏能看到
  "style/font_face": "明兰"  
  # 字號,只認數字的,不認「五號」、「小五」這樣的
  "style/font_point": 16     
横排与竖排候选码

ibus_rime.custom.yaml添加如下内容:

patch:
  style/horizontal: true
定制皮肤

:ibus用户 ibus_rime.custom.yaml 不包含控制配色、字體字號等外觀樣式的設定項。

Rime 中,输入法的显示效果称为「颜色主题」(color scheme)。在网上看到一个有趣的主题,如何添加到 Rime 中使用呢?假如我们要加入这里提供的「丹青」主题,在系统 custom 设置文件中加入以下配置即可:

# 在配色方案列表裏加入標識爲 tantsing 的新方案
  "preset_color_schemes/tantsing":  
    author: Mijiag
    back_color: 0xE3E3E3
    border_color: 0x000000
    candidate_text_color: 0x000000
    comment_text_color: 0x474747
    hilited_back_color: 0x1A0791
    hilited_candidate_back_color: 0x6F0B73
    hilited_candidate_text_color: 0xE3E3E3
    hilited_text_color: 0xE3E3E3
    name: "丹青/Tantsing"
    text_color: 0x000000

引用该主题的时候,使用名字 tantsing

# squirrel.custom.yaml
patch:
  style:
    color_scheme: tantsing
    horizontal: true
    inline_preedit: true
    font_point: 16
    corner_radius: 5
    candidate_format: "%c\u2005%@ \u2005"

如果要自己制作 Rime 主题,「Rime 西米」是一款网页端工具,可以辅助制作,实时渲染颜色,便于查看最终显示效果。这里有一些预定义的主题可供使用。

输入符号

符号文件 /usr/share/rime-data/symbols.yaml 开头已经说明了使用方法:

# Usage: patch your Rime schema to enable /X symbols:
# patch:
#   punctuator/import_preset: symbols
#   recognizer/patterns/punct: '^/([0-9]0?|[A-Za-z]+)$'

想在朙月拼音·简化字 luna_pinyin_simp 方案下输入符号,就新建 luna_pinyin_simp.custom.yaml

patch:
  punctuator/import_preset: symbols
  recognizer/patterns/punct: '^/([0-9]0?|[A-Za-z]+)$'

重新部署生效。

输入符号请键入识别码:

  • 星号 /xh
  • 箭头 /jt
  • 數字 /1
  • 更多符号参阅文件 symbols.yaml

其他方案下输入符号,照葫芦画瓢。

符号自定义

拷贝 /usr/share/rime-data/symbols.yaml~/.config/ibus/rime/symbols.custom.yaml。在末尾添加自定义符号:

# 个人常用信息
    '/yx': [ xiaoming@gmail.com, xiaoming@163.com, 1234567910 ] 
# 快速输入勾和叉 
    '/gc': [ , , ,  ]

想在朙月拼音·简化字 luna_pinyin_simp 方案下输入符号,就修改 luna_pinyin_simp.custom.yaml 文件内容为:

patch:
  punctuator/import_preset: symbols.custom
  recognizer/patterns/punct: '^/([0-9]0?|[A-Za-z]+)$'

重新部署生效。

然后在中文模式下,输入 /gc,就会显示出自定义的符号,输入对应的数字,符号就会上屏。

输入直角引号

有的人喜欢在写作的时候使用直角引号:「」『』,Rime 在 symbols.yaml 里面,已经提供了这个功能,不过是在 [] 按键上提供的,中文输入法状态下,按下[ (]),返回的结果中包含 (),如果按住 Shift 键,按下 [ (]),返回的结果中包含 ()。

但是因为这毕竟是引号,最好是按下引号的时候,能够输出直角引号,在symbols.custom.yaml 中,找到 punctuator 部分下的 hafl_shape (半角的意思)下面,把下面的映射

'''' : { pair: [ '‘', '’' ] }
'"' : { pair: [ '“', '”' ] }

改成

'''' : { pair: [ '『', '』' ] }
'"' : { pair: [ '「', '」' ] }

这样就可以直接输入直角引号了,另外一种方式就是在词典中添加直角引号映射,在jdhao.dict.yaml 中加入下面的映射即可:

「」 syh 1000
『』 dyh 1000
扩展词库

下载Rime 擴充詞庫

luna_pinyin.hanyu.dict.yaml
luna_pinyin.cn_en.dict.yaml
luna_pinyin.extended.dict.yaml
luna_pinyin.poetry.dict.yaml

接着将四个文件移动到用户资料夹 ~/.config/ibus/rime 下。

新增一個自訂的 luna_pinyin_simp.extended.dict.yaml 檔案:

# 以下禁用了默认词库同时不启用默认的“八股文”词库及词频系统,如果您不希望候选词中的出现繁体字、方框字的话
---
name: luna_pinyin_simp.extended
version: "2022.08.21"
sort: by_weight
use_preset_vocabulary: false #是否启用默认的“八股文”词库及词频系统,如需启用请设为 true 
import_tables: #在此导入词库
  #- luna_pinyin
  - luna_pinyin.hanyu
  - lluna_pinyin.cn_en
  - luna_pinyin.extended
  - luna_pinyin.poetry
...

接着再於 luna_pinyin_simp.custom.yaml 中將 translator/dictionary 設置成此字典檔即可

patch:
  translator/dictionary: luna_pinyin_simp.extended # 词典名字可自定义,保持一致即可

重新部署生效。

其他扩展词库:

增加自己的词库

我们可以仿照上一步的词典文件建立自己额外的词典,增加自己的词汇。例如,建立名为 my.dict.yaml 的文件,然后参照 luna_pinyin_simp.cn_en.dict.yaml 添加几个自己常用的词汇,文件内容如下:

# my.dict.yaml 文件内容
# Rime dictionary
# encoding: utf-8
#

---
name: my
version: "2020.05.28"
sort: by_weight
use_preset_vocabulary: true
...

GitHub github 100
Stack Overflow so 1000

词典的格式为: 词汇<Tab>编码<Tab>词频,各个项目之间必须用 Tab(也就是制表符 )分割。一个最保险的方法就是,复制粘贴。词频部分可以不要。

然后在 luna_pinyin_simp.extended.dict.yamlimport_tables 中加上自己建立的词汇。

import_tables:
  - my

一切添加妥当之后,重新部署生效。

默认英文

如果经常和英语打交道,偶尔输入汉字,可以把朙月拼音初始状态设为英语,需要时再切回中文。参考 这里 给出的说明,在 luna_pinyin_simp.custom.yaml 文件中加入下面的设置:

patch:
  "switches/@0/reset": 1  # 初始的 ascii mode 设置为「西文」

意思就是將 switcher 列表中的第一個元素(即 ascii_mode 開關)的初始值重設爲狀態1(即「英文」)。

模糊拼音

这里是官方给的一个模板 (朙月拼音)。将模板剪贴进 ~/.config/ibus/rime/luna_pinyin_simp.custom.yaml 文件中,然后需要哪组就去掉那一行前面的 # 即可。

# luna_pinyin.custom.yaml
#
# 【朙月拼音】模糊音定製模板
#   佛振配製 :-)
#
# 位置:
# ~/.config/ibus/rime  (Linux)
# ~/Library/Rime  (Mac OS)
# %APPDATA%\Rime  (Windows)
#
# 於重新部署後生效
#

patch:
  'speller/algebra':
    - erase/^xx$/                      # 第一行保留

    # 模糊音定義
    # 需要哪組就刪去行首的 # 號,單雙向任選
    #- derive/^([zcs])h/$1/             # zh, ch, sh => z, c, s
    #- derive/^([zcs])([^h])/$1h$2/     # z, c, s => zh, ch, sh

    #- derive/^n/l/                     # n => l
    #- derive/^l/n/                     # l => n

    # 這兩組一般是單向的
    #- derive/^r/l/                     # r => l

    #- derive/^ren/yin/                 # ren => yin, reng => ying
    #- derive/^r/y/                     # r => y

    # 下面 hu <=> f 這組寫法複雜一些,分情況討論
    #- derive/^hu$/fu/                  # hu => fu
    #- derive/^hong$/feng/              # hong => feng
    #- derive/^hu([in])$/fe$1/          # hui => fei, hun => fen
    #- derive/^hu([ao])/f$1/            # hua => fa, ...

    #- derive/^fu$/hu/                  # fu => hu
    #- derive/^feng$/hong/              # feng => hong
    #- derive/^fe([in])$/hu$1/          # fei => hui, fen => hun
    #- derive/^f([ao])/hu$1/            # fa => hua, ...

    # 韻母部份
    #- derive/^([bpmf])eng$/$1ong/      # meng = mong, ...
    #- derive/([ei])n$/$1ng/            # en => eng, in => ing
    #- derive/([ei])ng$/$1n/            # eng => en, ing => in

    # 樣例足夠了,其他請自己總結……

    # 反模糊音?
    # 誰說方言沒有普通話精確、有模糊音,就能有反模糊音。
    # 示例爲分尖團的中原官話:
    #- derive/^ji$/zii/   # 在設計者安排下鳩佔鵲巢,尖音i只好雙寫了
    #- derive/^qi$/cii/
    #- derive/^xi$/sii/
    #- derive/^ji/zi/
    #- derive/^qi/ci/
    #- derive/^xi/si/
    #- derive/^ju/zv/
    #- derive/^qu/cv/
    #- derive/^xu/sv/
    # 韻母部份,只能從大面上覆蓋
    #- derive/^([bpm])o$/$1eh/          # bo => beh, ...
    #- derive/(^|[dtnlgkhzcs]h?)e$/$1eh/  # ge => geh, se => sheh, ...
    #- derive/^([gkh])uo$/$1ue/         # guo => gue, ...
    #- derive/^([gkh])e$/$1uo/          # he => huo, ...
    #- derive/([uv])e$/$1o/             # jue => juo, lve => lvo, ...
    #- derive/^fei$/fi/                 # fei => fi
    #- derive/^wei$/vi/                 # wei => vi
    #- derive/^([nl])ei$/$1ui/          # nei => nui, lei => lui
    #- derive/^([nlzcs])un$/$1vn/       # lun => lvn, zun => zvn, ... 
    #- derive/^([nlzcs])ong$/$1iong/    # long => liong, song => siong, ...
    # 這個辦法雖從拼寫上做出了區分,然而受詞典制約,候選字仍是混的。
    # 只有真正的方音輸入方案纔能做到!但「反模糊音」這個玩法快速而有效!

    # 模糊音定義先於簡拼定義,方可令簡拼支持以上模糊音
    - abbrev/^([a-z]).+$/$1/           # 簡拼(首字母)
    - abbrev/^([zcs]h).+$/$1/          # 簡拼(zh, ch, sh)

    # 以下是一組容錯拼寫,《漢語拼音》方案以前者爲正
    - derive/^([nl])ve$/$1ue/          # nve = nue, lve = lue
    - derive/^([jqxy])u/$1v/           # ju = jv,
    - derive/un$/uen/                  # gun = guen,
    - derive/ui$/uei/                  # gui = guei,
    - derive/iu$/iou/                  # jiu = jiou,

    # 自動糾正一些常見的按鍵錯誤
    - derive/([aeiou])ng$/$1gn/        # dagn => dang 
    - derive/([dtngkhrzcs])o(u|ng)$/$1o/  # zho => zhong|zhou
    - derive/ong$/on/                  # zhonguo => zhong guo
    - derive/ao$/oa/                   # hoa => hao
    - derive/([iu])a(o|ng?)$/a$1$2/    # tain => tian

  # 分尖團後 v => ü 的改寫條件也要相應地擴充:
  #'translator/preedit_format':
  #  - "xform/([nljqxyzcs])v/$1ü/"
同步用户资料

默认地,词典快照备份到 ~/.config/ibus/rime/sync/UUID 这个地方。我们可以设定同步的目标文件夹,直接编辑 ~/.config/ibus/rime/installation.yaml

sync_dir: '/DATA/Backup/RimeSync'

然后,点击输入法程序指示器选择「同步」。你的 用户配置用户词库 等都会被放在目标文件夹。

注意!可能有些你自己添加的文件不会被备份,注意下就行。

我们可以借助移动存储设备,或在线存储服务如百度网盘、坚果云等,在多台电脑及不同系统之间同步用户词典和用户设定。在新电脑上配置一下 installation.yaml 文件,执行 部署 -> 同步 -> 部署 ,你的 用户配置用户词库 都回来了。

新世纪五笔

参阅 https://github.com/GuoBinyong/wubixinshiji。[Rime输入法之五笔自动上屏](https://blog.csdn.net/fonaix/article/details/102405204)。

后续配置来自视频 rime 中的小狼毫输入法的安装和基础自定义 所分享的文件: https://www.lanzous.com/ia2g86h。

Easy english

用于输入英文。拷贝下面两个文件到「用户资料夹」:

  • easy_en.schema.yaml
  • easy_en.dict.yaml

vim default.custom.yaml 添加输入方案:

  schema_list:
    - schema: wubixinshiji    # 新世纪五笔
    - schema: wubixinshiji_pinyin    # 新世纪五笔·拼音
    - schema: luna_pinyin_simp    # 朙月拼音·简化字
    - schema: easy_en
    - schema: pinyin_simp    # 袖珍简化字拼音
输入日期

将文件 rime.lua 拷贝到 ~/.config/ibus/rime/ 下,在方案配置文件比如 wubi86.schema.yamlengine\translators: 下面添加滤镜引用:

  translators:
    - lua_translator@date_translator
    - lua_translator@week_translator
rime-emoji
  1. 下載opencc檔案夾內容,將完整檔案夾放入Rime用戶檔案夾內
  2. emoji_suggestion.yaml內的內容加入至想添加Emoji的方案custom檔中

我安装后,没有显示emoji,所以还是用 gnome-characters 好了。

切换中英文

切换中英文,rime在默认情况下,输入中文时按shift键会切换为英文,但字符还在,需要按回车输出字符,有的用户可能不习惯shift这个键位,或者不习惯按shift不直接上屏,还要按一下回车,对此,我们可以做出修改 default.custom.yaml

patch:
  ascii_composer/good_old_caps_lock: true
  ascii_composer/switch_key:
    Caps_Lock: clear
    Shift_L: commit_code
    Shift_R: inline_ascii
    Control_L: noop
    Control_R: noop

注意换行前空格以及冒号后的空格,还有字母大小写,前两行代码先不看,下面五行分别代表:

  • caps_lock即为大写键,shift_L即为左shift,R是右,control_L即为左ctrl键,R为右
  • 冒号后的字符即为这个键位的操作
    • clear表示按下此键后已输入的字符清除,同时rime输入状态切换为英文,大写键一定不能改为noop,否则大写英文将会无法输出,很多教程里都改为了noop,这点值得注意
    • commit_code即为提交代码,就是将已输入的字符上屏,同时输入法切换为英文
    • inline_ascii即为插入字符,就是已输入的字符为上屏前,按此键后输入法转为英文,可以接着输入,回车键再上屏
    • noop就是这个键在输入法里不会有任何操作

各个键位和代码的意思已经介绍完了,可以按自己的喜好,自行修改。

不过仍有部分用户从win7开始是用的ctrl键+空格键切换中英文,且习惯输入法为默认英文。RIME的快捷键是在“default.yaml”文档中定义的,我们可以将“default.yaml”文档中相关代码直接复制过来,接上面代码:

key_binder:
  bindings:
    - {accept: "Control+Shift+2", toggle: ascii_mode, when: always}

注意到ascii_mode了吗,“字符模式”即为我们需要的中英文切换快捷键,默认快捷键为ctrl+shift+2,我们可以将其代码修改为Control+space即为ctrl+空格,注意大小写,这样我们就能让输入法默认英文同时用回习惯的操作

至此,关于default.custom.yaml的设置基本完成,样例如下:

patch:
  ascii_composer/good_old_caps_lock: true
  ascii_composer/switch_key:
    Caps_Lock: clear
    Shift_L: noop
    Shift_R: noop
    Control_L: noop
    Control_R: noop
  key_binder/bindings:
    - { when: always, accept: Control+space, toggle: ascii_mode }
    - { when: has_menu, accept: minus, send: Page_Up }
    - { when: has_menu, accept: equal, send: Page_Down }

注意:如果没有Page_Up,Page_Down两行,就没办法用 + 与 - 进行翻页了。

清空候选词

我使用ibus-rime,有一个很大的缺点是如果输入没有完成的情况下,移动鼠标,其他的输入法未完成的内容都会被清空,而只有rime不会,而且会重复输出未完成的内容,这点很烦人,也不知道哪里能够设置。

  1. 定制快捷键

    patch:
      key_binder/bindings:
        - { when: composing, accept: Control+g, send: Escape }
    
  2. 使用 Sitch input sources individually for each window

Wallpapers

Gnome Background

圖形使用者介面程式

可以透過「圖形使用者介面程式」,來更改「桌面圖片」。在桌面,按下「滑鼠右鍵」,就會出現一個選單,選擇「Change Background…」。就會出現設定更改「桌面圖片」的操作介面。

也就是「Settings / Background」。

gnome-control-center background

指令操作

也可以透過「gsettings」這個指令,來更改「桌面圖片」。

gsettings set org.gnome.desktop.background picture-uri 'file:///usr/share/backgrounds/Blue_flower_by_Elena_Stravoravdi.jpg'

在測試的過程中發現,若使用「暗色系」的「佈景主題」,則要執行下面指令

gsettings set org.gnome.desktop.background picture-uri-dark 'file:///usr/share/backgrounds/Blue_flower_by_Elena_Stravoravdi.jpg'

小技巧

切換顯示桌面的按鍵組合是「Win + d」。

$ gsettings get org.gnome.desktop.wm.keybindings show-desktop
['<Primary><Super>d', '<Primary><Alt>d', '<Super>d']

Apps

Variety

默认仓库版本可能较低,导致一些 Bug,因此最好用 PPA

sudo add-apt-repository ppa:variety/stable
sudo apt update
sudo apt install variety -y

支持 wallhaven,添加 keywords 就可以使用了,配置文件在 ~/.config/variety/variety.conf

  • Touhou
  • Azur Lane
  • Genshin Impact
  • anime girls
  • cosplay
  • GUWEIZ
  • WLOP

unsplash.sh

添加脚本

$ vi $HOME/Pictures/unsplash.sh
#!/usr/bin/bash

UNSPLASH_DIR=$HOME/Pictures/Unsplash

if [ ! -d ${UNSPLASH_DIR} ]; then
    mkdir -p ${UNSPLASH_DIR}
fi

URL_LOCATION=$(curl -I https://source.unsplash.com/daily | grep Location | cut -d' ' -f 2)
WALLPAPER_NAME=$(echo $URL_LOCATION | egrep -o 'photo[a-z0-9-]+')
WALLPAPER_FORMAT=$(echo $URL_LOCATION | egrep -o 'fm=[a-z]+' | cut -d'=' -f 2)
wget --no-proxy -O ${UNSPLASH_DIR}/${WALLPAPER_NAME}.${WALLPAPER_FORMAT} ${URL_LOCATION}

可以使用 Crontab 定时切换壁纸:

$ crontab -e
0 12 * * * /home/vane/Pictures/unsplash.sh

除了使用 crontab 外,还可以使用 Startup Applications Preferences 添加一个启动项。

wallhaven.sh

wallhaven图片右键下载的是原图,不是缩略图。

$ vi $HOME/.wallhaven/wallhaven.sh
#!/bin/bash

WORK_DIR=$HOME/.wallhaven
SAVE_DIR=$HOME/Pictures/wallhaven
IMG_URL=https://w.wallhaven.cc/full

function GetListing()
{
  echo 'get listing'
  listing=$(curl https://wallhaven.cc/api/v1/search?apikey=<API KEY>&categories=010&purity=111&atleast=1920x1080&ratios=16x9&sorting=random&order=desc&page=1)
  echo 'save listing'
  echo $listing | jq -r '.data[].path' | awk -F '/' '{print $NF}' > $WORK_DIR/listing
  echo 'save res'
  cat $WORK_DIR/listing | wc -l > $WORK_DIR/res
  SetWallpaper
}

function SetWallpaper()
{
  if [ -a $WORK_DIR/res ]; then
    echo 'read res'
    read res  < $WORK_DIR/res
    if [ $res -ne 0 ]; then 
      echo 'get img'
      img=$(cat $WORK_DIR/listing | tail -${res} | head -1)
      echo "down $img from $IMG_URL/${img:10:2}/$img"
      curl -o $SAVE_DIR/$img $IMG_URL/${img:10:2}/$img
      if [ $? -eq 0 ]; then
        echo 'set wallpaper'
        cp $SAVE_DIR/$img $HOME/Wallpaper
        echo 'res-1'
        echo $(($res - 1)) > $WORK_DIR/res
        echo 'exit'
        exit 0
      else
        echo 'download error'
        SetWallpaper
      fi
    else
      echo 'res=0'
      GetListing
    fi
  else
    echo 'no res'
    GetListing
  fi
}

SetWallpaper

使用 Shell 脚本来处理 JSONjq Manualwallhaven API v1 Documentation

一般文件内容开头都会有一个文件类型的标记,根据文件名后缀只是一个快捷的方法,不用读取文件内容就判断文件类型,但不是唯一的方法。

$ crontab -e
0 12 * * * /home/vane/.wallhaven/wallhaven.sh

Gsettings 无法在 Cron 中使用:出现此问题是因为 cron 仅使用一组非常有限的环境变量。 唯一一个负责在将其设置为 cron 作业时以正确方式运行问题脚本的环境变量是 DBUS_SESSION_BUS_ADDRESS。

astronomy.sh

#!/bin/bash
API_KEY=zTL5rJmctXwHcsjfCSalfDRNFTeaVYa9FxgINVVU
HTTP_REQUEST=https://api.nasa.gov/planetary/apod?api_key=$API_KEY
HTTP_RESPONSE=$(curl $HTTP_REQUEST)
IMG_HDURL=$(echo $HTTP_RESPONSE | jq -r '.hdurl')
IMG_FILENAME=$(echo ${IMG_HDURL##*/})
curl -o $HOME/DataOne/Images/Astronomy/$IMG_FILENAME $IMG_HDURL
cp -av $HOME/DataOne/Images/Astronomy/$IMG_FILENAME $HOME/Wallpaper

Wallpaper Slideshows

2018-04-23 18:53

使用一个简单的 XML,你就可以设置 GNOME 能够在桌面上显示一个幻灯片。

在 GNOME 中,一个非常酷、但却鲜为人知的特性是它能够将幻灯片显示为墙纸。你可以从 GNOME 控制中心的 “背景设置” 面板中选择墙纸幻灯片。在预览的右下角显示一个小时钟标志,可以将幻灯片的墙纸与静态墙纸区别开来。

一些发行版带有预装的幻灯片壁纸。 例如,Ubuntu 包含了库存的 GNOME 定时壁纸幻灯片,以及 Ubuntu 壁纸大赛胜出的墙纸。

如果你想创建自己的自定义幻灯片用作壁纸怎么办?虽然 GNOME 没有为此提供一个用户界面,但是在你的主目录中使用一些简单的 XML 文件来创建一个是非常容易的。 幸运的是,GNOME 控制中心的背景选择支持一些常见的目录路径,这样就可以轻松创建幻灯片,而不必编辑你的发行版所提供的任何内容。

开始

使用你最喜欢的文本编辑器在 $HOME/.local/share/gnome-background-properties/ 创建一个 XML 文件。 虽然文件名不重要,但目录名称很重要(你可能需要创建该目录)。 举个例子,我创建了带有以下内容的 /home/ken/.local/share/gnome-background-properties/osdc-wallpapers.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">
<wallpapers>
 <wallpaper deleted="false">
   <name>Opensource.com Wallpapers</name>
   <filename>/home/ken/Pictures/Wallpapers/osdc/osdc.xml</filename>
   <options>zoom</options>
 </wallpaper>
</wallpapers>

每一个你需要包含在 GNOME 控制中心的 “背景面板”中的每个幻灯片或静态壁纸,你都要在上面的 XML 文件需要为其增加一个 <wallpaper> 节点。

在这个例子中,我的 osdc.xml 文件看起来是这样的:

<?xml version="1.0" ?>
<background>
  <static>
    <!-- Duration in seconds to display the background -->
    <duration>30.0</duration>
    <file>/home/ken/Pictures/Wallpapers/osdc/osdc_2.png</file>
  </static>
  <transition>
    <!-- Duration of the transition in seconds, default is 2 seconds -->
    <duration>0.5</duration>
    <from>/home/ken/Pictures/Wallpapers/osdc/osdc_2.png</from>
    <to>/home/ken/Pictures/Wallpapers/osdc/osdc_1.png</to>
  </transition>
  <static>
    <duration>30.0</duration>
    <file>/home/ken/Pictures/Wallpapers/osdc/osdc_1.png</file>
  </static>
  <transition>
    <duration>0.5</duration>
    <from>/home/ken/Pictures/Wallpapers/osdc/osdc_1.png</from>
    <to>/home/ken/Pictures/Wallpapers/osdc/osdc_2.png</to>
  </transition>
</background>

上面的 XML 中有几个重要的部分。 XML 中的 <background> 节点是你的外部节点。 每个背景都支持多个 <static><transition> 节点。

  • <static> 节点定义用 <file> 节点要显示的图像以及用 <duration> 显示它的持续时间。
  • <transition> 节点定义 <duration>(变换时长),<from><to> 定义了起止的图像。

全天更换壁纸

另一个很酷的 GNOME 功能是基于时间的幻灯片。 你可以定义幻灯片的开始时间,GNOME 将根据它计算时间。 这对于根据一天中的时间设置不同的壁纸很有用。 例如,你可以将开始时间设置为 06:00,并在 12:00 之前显示一张墙纸,然后在下午和 18:00 再次更改。

这是通过在 XML 中定义 <starttime> 来完成的,如下所示:

<starttime>
    <!-- A start time in the past is fine -->
    <year>2017</year>
    <month>11</month>
    <day>21</day>
    <hour>6</hour>
    <minute>00</minute>
    <second>00</second>
</starttime>

上述 XML 文件定义于 2017 年 11 月 21 日 06:00 开始动画,时长为 21,600.00,相当于六个小时。 这段时间将显示你的早晨壁纸直到 12:00,12:00 时它会更改为你的下一张壁纸。 你可以继续以这种方式每隔一段时间更换一次壁纸,但确保所有持续时间的总计为 86,400 秒(等于 24 小时)。

GNOME 将计算开始时间和当前时间之间的增量,并显示当前时间的正确墙纸。 例如,如果你在 16:00 选择新壁纸,则GNOME 将在 06:00 开始时间之后显示 36,000 秒的适当壁纸。

实用程序

macOS Dynamic Wallpaper 实例

<!-- Instructions:
- Download and unzip Mojave dynamic background here: https://files.rb.gd/mojave_dynamic.zip 
- Rename the extracted folder as "mojave-background" (Excuse the trouble but I renamed it on my machine and already use that path in the XML file)
- Save this xml file next to the Mojave background files
- Fix the path to the background images below (better using absolute path)
- Lastly, either: 
  + GNOME: Use gnome-tweaks tool to select this XML as wallpaper (as default wallpaper settings won't let you choose wallpaper from custom path)
  + MATE: Go to background setting (in Appearance) > Choose +Add... > make sure **All files** filter is selected at the bottom right > Then choose mojave.xml
-->
<background>
  <starttime>
    <year>2014</year>
    <month>01</month>
    <day>11</day>
    <hour>0</hour>
    <minute>00</minute>
    <second>00</second>
  </starttime>
  <!-- 00:00 -->
  <static>
    <duration>10795.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_15.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_15.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_16.jpeg</to>
  </transition>
  <!-- 03:00 -->
  <static>
    <duration>10795.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_16.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_16.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_1.jpeg</to>
  </transition>
  <!-- 05:00 -->
  <static>
    <duration>3595.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_1.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_1.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_2.jpeg</to>
  </transition>
  <!-- 06:00 -->
  <static>
    <duration>3595.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_2.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_2.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_3.jpeg</to>
  </transition>
  <!-- 07:00 -->
  <static>
    <duration>3595.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_3.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_3.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_4.jpeg</to>
  </transition>
  <!-- 08:00 -->
  <static>
    <duration>3595.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_4.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_4.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_5.jpeg</to>
  </transition>
  <!-- 09:00 -->
  <static>
    <duration>3595.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_5.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_5.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_6.jpeg</to>
  </transition>
  <!-- 10:00 -->
  <static>
    <duration>3595.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_6.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_6.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_7.jpeg</to>
  </transition>
  <!-- 11:00 -->
  <static>
    <duration>7195.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_7.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_7.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_8.jpeg</to>
  </transition>
  <!-- 13:00 -->
  <static>
    <duration>3595.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_8.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_8.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_9.jpeg</to>
  </transition>
  <!-- 14:00 -->
  <static>
    <duration>3595.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_9.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_9.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_10.jpeg</to>
  </transition>
  <!-- 15:00 -->
  <static>
    <duration>3595.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_10.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_10.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_11.jpeg</to>
  </transition>
  <!-- 16:00 -->
  <static>
    <duration>3595.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_11.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_11.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_12.jpeg</to>
  </transition>
  <!-- 17:00 -->
  <static>
    <duration>3595.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_12.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_12.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_13.jpeg</to>
  </transition>
  <!-- 18:00 -->
  <static>
    <duration>7195.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_13.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_13.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_14.jpeg</to>
  </transition>
  <!-- 20:00 -->
  <static>
    <duration>10795.0</duration>
    <file>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_14.jpeg</file>
  </static>
  <transition type="overlay">
    <duration>5.0</duration>
    <from>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_14.jpeg</from>
    <to>/home/thanh/Pictures/wallpapers/mojave-background/mojave_dynamic_15.jpeg</to>
  </transition>
</background>
  • 最好先根据图片数量,将时间段划分出来,之后再编写代码。时间段划分可以参考日出日落时间表
  • ~~更进一步,用 ffmpeg 创建足够多的帧,Dynamic Wallpaper 或许可以变成 Video Wallpaper 了,~~经过测试,时间精度也限定为 0.1s,所以并不适合做为 Video Wallpaper。
  • overlay 和 5.0 的使得过渡非常自然。

Light and Dark Wallpaper

2022-04-13 23:38

一份简单的指南:如何针对 GNOME 桌面环境来创建你的自定义的深色和浅色壁纸。

GNOME 42 将备受期待的深浅主题带到 GNOME 桌面环境。它也带来壁纸的深色和浅色版本,当你切换深色或浅色主题时,它会自动地转换。

因此,默认情况下,GNOME 给予你一套预配置的深色和浅色壁纸。但是如果你想要在主题更改时自动地转换成另一种不同的壁纸要怎么做呢?

下面是如何在 GNOME 中配置和创建你自己的深浅壁纸的方法。

自定义的深浅壁纸

  1. 确保你手边有两个版本的壁纸。一般来说,它们应该是标准的 PNG 或 JPG 图像文件。

  2. 我们需要为我们自己创建一个模式文件。壁纸的自动更换是由 XML 文件处理的,它定义了特定的深色和浅色的背景标记。因此,我们将为壁纸创建我们自己的 XML 文件。

    <?xml version="1.0"?>
    <!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">
    <wallpapers>
      <wallpaper deleted="false">
        <name>Default Background</name>
        <filename>@BACKGROUNDDIR@/adwaita-l.webp</filename>
        <filename-dark>@BACKGROUNDDIR@/adwaita-d.webp</filename-dark>
        <options>zoom</options>
        <shade_type>solid</shade_type>
        <pcolor>#3071AE</pcolor>
        <scolor>#000000</scolor>
      </wallpaper>
    </wallpapers>
    

    你能够会在这个文件中看到两个标记 – filenamefilename-dark。这两个 XML 标记包含这两个壁纸的完整的限定的路径(绝对路径)。现在,在这两个标记下添加你的图像文件的路径。

  3. 把这个文件保存到 /home/<your_name>/.local/share/gnome-background-properties,文件名任意。

这样,你就准备好了所有的东西。最后,打开 “设置Settings” 并转到 “外观” 标签页,你应该会看到一个新的壁纸选项。

选择你自己的自定义的深浅壁纸,尽情享受。

获取动态壁纸

当然,你必然会想,谁有时间去查找和创建壁纸的日夜版本?这里有一些网站来向你提供预制好的动态壁纸,你可以轻松地下载和安装。

How to find and make dynamic Mac wallpapers:

此外,如果你打算从上述网站下载,请记住该网站的图像文件是 heic 格式的,因为这个网站是针对 macOS 的。高效视频编码High-Efficiency Video Coding(HEIC)是苹果的专有的 HEIF(高效图像文件High-Efficiency Image File)专有版本。

那么,如何在 Linux 系统中转换它们? 好吧,在 Ubuntu 中,你需要一个驱动程序来查看和转换动态的 heic 图像文件。打开一个终端,运行下面的命令开安装驱动程序。

sudo apt install heif-gdk-pixbuf

针对使用 KDE Plasma 的用户(没有这个插件的帮助,Plasma 应用程序就不能打开 heic 格式的图像文件):

sudo apt install qt-heif-image-pluginsudo dnf install qt-heif-image-plugin

Convert HEIC

  • using heif-convert

    sudo apt install libheif-examples
    heif-convert input.HEIC output.JPG
    

    后面发现解压文件的序号与图片的播放顺序不一致,因此需要预览图来对照调整顺序——图片少也不难,图片多的话,也不是全部都打乱了,只是一两张顺序而已。

  • using ImageMagick

    22.04.1 仓库 ImageMagick 6.9.11 版本低了,只能转换成一张 png,因此使用官网 portable 版本

    $ ./magick convert burst.heic output.jpg
    convert: no decode delegate for this image format `HEIC' @ error/constitute.c/ReadImage/741.
    convert: no images defined `output.jpg' @ error/convert.c/ConvertImageCommand/3342.
    

    需要手动编译以支持HEIC

HEIF metadata

  • 使用 libheif(depend by heif-gdk-pixbuf package) 提供的 heif-info 工具,heif-info file.heif 可以列出每个图片简略信息(没啥用),heif-info -d file.heif 可以列出 low-level 信息:

    • 每个 item_type: grid 就是照片起始位置,会发现其 item_IDheif-info file.heif 输出一致。
  • 参考 wallutils 的 issue:Support macOS dynamic wallpapers

    You can inspect this metadata with the following steps:

    sudo apt install libimage-exiftool-perl
    exiftool wallpaper.heic
    

    Under the key “Solar” there’s a base64 encoded plist file. You can decode this with:

    sudo apt install libplist-utils
    echo "[Base64 string]" | base64 -d - | plistutil
    

    所谓 Solar,参考制作 MacOS Dynamic Wallpaper 的开源项目 wallpapper 的博客文章 macOS Mojave dynamic wallpapers (II):Thanks to altitude and azimuth w exactly know where the Sun was when image was taken. This idea is brilliant, because thanks to this information macOS can change images differently during Summer and during Winter. System knows where the Sun is and it will choose image which was taken in similar conditions. Brilliant.(即,计算机以拍照者的视角展示照片)

    最终 wallutils 是部分完成了这个功能了,使用了 xyproto/heic 这个库,实现在这里,可以解析 H24 时间格式,但是不能解析 Solar 格式的。其实就是乘个 24 就得出时钟了。我的方法是 24 乘以最小的数值,得出初始时间放入 <starttime>,以该时间对应的照片开头(合理即可),按照照片数量等分 24 小时放入 <duration>

    Solar 话我这里我简单地计算(复杂的不会啊!😂):观察 azimuth,找到第一个 0°~180°的数值(天体上升,180°~360° 天体下降),将其乘以 24 / 360,得出其初始时间,放入 <starttime>,然后以该时间对应的照片开头(合理即可),按照照片数量等分 24 小时放入 <duration>

Real world examples

mojave-timed.xml:还可以这样写,全部都是 transition,没有 static 部分

<background>
  <starttime>
    <year>2000</year>
    <month>01</month>
    <day>01</day>
    <hour>01</hour>
    <minute>00</minute>
    <second>00</second>
  </starttime>

  <transition type="overlay">
    <duration>14400.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0100.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0500.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>3600.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0500.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0600.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>3600.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0600.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0700.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>3600.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0700.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0800.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>3600.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0800.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0900.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>3600.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0900.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1000.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>3600.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1000.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1100.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>3600.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1100.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1200.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>4800.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1200.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1320.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>4800.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1320.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1440.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>4800.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1440.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1600.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>4800.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1600.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1720.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>4800.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1720.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1840.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>4800.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-1840.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-2000.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>3600.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-2000.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-2100.jpg</to>
  </transition>
  <transition type="overlay">
    <duration>14400.0</duration>
    <from>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-2100.jpg</from>
    <to>/usr/share/backgrounds/gnome/mojave/mojave_dynamic-0100.jpg</to>
  </transition>
</background>

視頻動壁紙

1 Feb, 2022

日常使用的話,我是不會去碰動態壁紙之類的東西,因爲這些東西很影響我的注意力,而且這也沒多大的必要。但你十分喜歡這種十分炫酷的視頻動態壁紙的話,希望這篇東西可能可以幫到你吧。

舉個例子:我的屏幕大小是 3440 x 1440 ,使用 這個視頻 作爲動態壁紙

命令如下:(參數就看你需求改就是了這裏只是演示一下)

xwinwrap -g 3440x1440 -ni -s -nf -b -un -ov -fdt -argb -- mpv -wid WID --ao=null --loop=inf --stop-screensaver=no --script-opts=ytdl_hook-ytdl_path=yt-dlp "https://www.youtube.com/watch?v=n9w_hZkbfoo"

注:因爲 youtube-dl 下載太慢這裏使用 youtube-dl 的一個 fork yt-dlp

如果你是要播放本地視頻,那麼改爲:

xwinwrap -g 3440x1440 -ni -s -nf -b -un -ov -fdt -argb -- mpv -wid WID --ao=null --loop=inf --stop-screensaver=no $VIDEO_PATH

Social

Telegram

先通过手机登录,再在电脑端登录。电脑先登录,手机老是收不到验证码。

简介

  • Telegram —— 中文名又称"电报",或简称"TG"。

  • Telegram 是跨平台的即时通信软件,其客户端是自由及开放源代码软件,但服务器是专有软件。

  • Telegram 在中国大陆境内无法直接连接,注册和使用都需要科学上网,请自备节点和工具。

  • 下载:Telegram 有官方版和第三方版本,但出于安全和隐私的考虑,推荐大家使用 Telegram 官方版客户端

推荐设置

  • Privacy and Security
    • Phone Number
      • 谁能看见我的手机号码:Nobody
      • 谁能通过手机号码找到我:My Contacts
    • Forwarded Messages:Nobody
    • Calls:Nobody
    • Groups:My Contacts
  • Local Passcode:本地密码只是本设备打开 Telegram 的应用密码
  • Two-Step Verification:为了账号安全,强烈推荐您设置两步验证密码。
  • Delete my account:推荐您设置为一年

隐私保护注意事项

  • 资料设置
    • 昵称及用户名:避免使用与其他社交平台相同或相似的昵称及用户名
    • 手机号码:在"设置——隐私——电话号码"中设置"不允许任何人查看我的手机号码"和"仅允许联系人通过手机号码找到我"。
  • 群组聊天:Telegram 的群聊是"不安全"的。 公开群组的所有聊天内容都可被其他人查看,即使他人并未注册 Telegram; 对于群组内的机器人,它们可以收集群组内的绝大部分消息。
  • 媒体文件:在分享照片时,请注意使用专业修图软件打码处理关键信息,并清除照片包含的地理位置信息
  • 分享链接:从其他平台分享内容至 Telegram 时,请注意清除分享链接中的用户 UserID 识别信息,他人完全有可能从您的分享链接中获取您的用户信息。
  • 第三方客户端:如无特殊需要,请使用官方 Telegram 客户端。第三方客户端有能力获取和控制您的账户,读取您全部的聊天记录,收集您设备的可识别信息,包括但不限于:手机号、设备型号、IMEI码、MAC码等。

常见问题及解答

  • 无法给他人发送私聊:“Sorry, you can only send messages to mutual contacts at the momet.”
    • @SpamBot
    • But I can’t message non-contacts!
    • No,I’ll never do any of this
  • 群组和频道有什么类型?有什么特点?
    • 群组(Group)或者频道(Channel)有两种类型。
      • 一种是公开群组(Public Group/Channel)
      • 一种是私有群组(Private Group/Channel)
    • 公开群组(Public Group/Channel) 有自定义设置的ID,所有人可以通过搜索功能,输入id查询到相应的群组。公开群组的历史消息对所有人可见,即使没加入公开群组,也可以查看群组历史消息。
    • 私有群组(Private Group/Channel) 没有自定义的ID,要加入只能通过点击邀请链接或者被邀请入群, 在私有群组,群主可以设定历史消息的可见性。而对于没有加入群组的人,则不可以查看群组的消息。
  • Telegram 用户名是什么?
    • 其他用户可以通过用户名找到您,您将出现在“全局结果”下的联系人搜索中。这样人们就可以在不知道您的电话号码的情况下通过 Telegram 与您联系。
    • 由于用户名的唯一性,可以防止他人盗用你的头像和昵称冒充你。
  • 如何添加联系人?:添加和删除联系人都是单向操作,对方设备并不会同步。
  • 添加非手机号码联系人后,对方能知道自己的手机号码吗?:如果想取消分享你的手机号,请到隐私设置(Privacy and Security)中找到手机号码(Phone Number)的设置,在里面移除对方即可。
  • 不登陆 Telegram 如何查看频道消息?:Telegram 公开频道可以直接通过浏览器输入 https://t.me/s/频道id 访问,不需要拥有TG账号。

进阶知识

什么是 MTProxy 代理?

  • MTProxy 是 Telegram 的官方项目,仅能用于代理 Telegram 软件
  • MTP 代理是在 Telegram 中内置的代理程序,可以直接在软件内配置,而不需要下载任何其他 App 来配置代理

主题与美化

美化主题频道

  • 官方 Desktop 桌面版主题频道 @themes
  • 官方 Android 安卓主题频道 @Androidthemes

Sticker Pack

用现成的图片集来制作 stickers pack。Linux 可以方便地使用 ImageMagick 来操作。

Telegram 要求 Sticker 图片为 PNG 格式,并且要有透明层,至少一边为 512 像素,另一边则不超过 512 像素。最大文件大小为 350KB。透明层就算了,我不会玩 PS。那么直接偷懒(死)来批量把当前目录下 JPG 和 PNG 混杂的图片们统一转换为 PNG 好了。

几条命令发给 stickers bot

  1. /newstickerpack
  2. 发送表情包的名字…
  3. 在内置的 emoji 中发送一个最符合你要发送图片的表情…
  4. 然后把对应的图片作为文件发送
  5. 如果还有其他图片的话重复 3-4
  6. 全部表情图片设置完毕,发送 /publish 命令
  7. 为你的 stickers pack 取一个短名字 (用于 URL)

使用EFB推送QQ与微信消息

导出 Telegram 贴图

默认 Desktop

[Desktop Entry]
Version=1.5
Name=Telegram Desktop
Comment=Official desktop version of Telegram messaging app
TryExec=/home/kurome/.telegram/Telegram
Exec=/home/kurome/.telegram/Telegram -workdir /home/kurome/.local/share/TelegramDesktop/ -- %u
Icon=telegram
Terminal=false
StartupWMClass=TelegramDesktop
Type=Application
Categories=Chat;Network;InstantMessaging;Qt;
MimeType=x-scheme-handler/tg;
Keywords=tg;chat;im;messaging;messenger;sms;tdesktop;
Actions=Quit;
SingleMainWindow=true
X-GNOME-UsesNotifications=true
X-GNOME-SingleWindow=true

[Desktop Action Quit]
Exec=/home/kurome/.telegram/Telegram -workdir /home/kurome/.local/share/TelegramDesktop/ -quit
Name=Quit Telegram
Icon=application-exit

xdg-open

xdg-open opens a file or URL in the user's preferred application. If a URL is provided the URL will be opened in the user's preferred web browser. If a file is provided the file will be opened in the preferred application for files of that type. xdg-open supports file, ftp, http and https URLs.

在设置了默认 desktop 文件后,在浏览器中点击 JOIN GROUP 依旧打不开 Telegram,有如下报错:

$ xdg-open tg://join?invite=xxxx
gio: tg://join?invite=xxxx: The specified location is not supported

参考xdg-open doesn’t recognize custom protocol解决:

xdg-mime default telegram.desktop x-scheme-handler/tg

Telegram 充當雲端筆記

Telegram本身有非常多的新闻、咨询以及网友们非常有深度的讨论,因此可以通过Saved Message或者建立群组频道来转存感兴趣的信息。farseerfc 的小窝 就有一个。

中文搜索

问题在哪

Telegram 群组和频道越来越多,消息也越来越多,但是搜索中文的消息却是一个很大的问题。

主要原因

Telegram 的搜索是以”词”为基础单位的,是以英文标点符号空格作为”词”的间隔。

这是以英文为基础的搜索方式,这样的方式对于英文的搜索就很方便,比如”hello”,用”he”就搜索不到,必须用”hello”,这就符合英文的语境,当我想要找”he”消息时并不想看到有”hello”的消息。

但是这种方式对于中文等语言来说就很不方便,中文是以字为单位的,按照上面的方式,比如消息内容”动态贴纸不能用这个bot导出”用”贴纸”或”导出”就不能搜索到此消息。

如何解决

知道问题出在哪儿?那又如何解决呢? 解决方案:

  • 发消息时以英文标点符号空格作为间隔,比如消息”动态贴纸不能用这个bot导出”,可以用”动态 贴纸 不能 用这个 bot 导出”方法发出,这样就可以用”动态”“贴纸”“不能”“导出”关键词搜索到此消息。
  • 发消息时可以加’tag’,比如想发送消息”ABCDEFG”,可以发送”#tag ABCDEFG”,下次可以用”#tag”关键词搜索找到都有这个标签的消息。
  • 已发的消息,以标点符号空格作为间隔单位搜索,比如”好像国区是没有,点链接提示转到国区,关掉就好了,账号可以在不同地区购买”,可以用”好像国区是没有”“点链接提示转到国区”“关掉就好了”“账号可以在不同地区购买”关键词搜索到此消息。

冻屏

Alex Fish, [17/08/2022 3:55 PM] 就点击不了,就拖动啊,super+鼠标拉,虽然快捷键也能操作就是了

Alex Fish, [17/08/2022 3:58 PM] 虽然快捷键也能操作就是了

Big V, [17/08/2022 3:58 PM] Advanced => Use system window frame Qt窗口绘制的锅

Profile Videos

20220820 暂时只有手机支持。

Mutt

Mutt 是一个基于文本的邮件客户端,因其强大的功能而闻名。 Mutt虽然已诞生二十多年了,但仍然是大量用户的首选邮件客户端。

Mutt主要侧重于作为邮件用户代理(MUA),最初是为了查看邮件而编写的。 与其他邮件应用程序相比,稍后实现的功能(检索,发送和过滤邮件)比较简单,因此用户可能希望使用外部应用程序来扩展Mutt的功能。

模块搭配方案

就像穿衣搭配一样,收件发件过滤邮件转发邮件各种功能都有很多种程序可以用,mutt怎么搭配呢?

常用选项有这些(User/Transport/Delivery):

  • MUA 收件:fetchmailgetmailOfflineIMAP
  • MTA 发件:sendmailmsmtppostfix。其中msmtp兼容强,postfix对国内不友好
  • MDA 分类: procmailmaildrop
  • 邮件编辑:VIM。

一般搭配是:

  • 老式搭配:mutt + getmail + sendmail + procmail
  • 新式搭配:mutt + fetchmail + msmtp + maildrop

这里我们用:mutt + fetchmail + msmtp + procmail

安装:

sudo apt install mutt fetchmail msmtp procmail -y

Mutt或各个写协作程序在配置前都是不能使用的,学习曲线还是比较陡峭的,所以要做好准备去花好一段去了解和学习各个部件。

大概的配置流程是:

  • 配置收件:~/.fetchmailrc
  • 配置过滤:~/.procmailrc
  • 配置发件:~/.msmtprc
  • 配置mutt框架本身:~/.muttrc

注意:初学过程中,不要一上来就配置mutt。最好是先从各个部件开始:收件->过滤邮件->阅读邮件->发件->mutt界面,按照这种顺序。

收件:配置Fetchmail

Fetchmail是由著名的《大教堂与集市》作者 Eric Steven Raymond 编写的。

Fetchmail是一个非常简单的收件程序,而且是前台运行一次性运行的,意思是:你每次手动执行fetchmail命令,都是在前台一次收取完,程序就自动退出了,不是像一般邮件客户端一直在后台运行。

注意:fetchmail只负责收件,而不负责存储!所以它是要调用另一个程序如procmail来进行存储的。

fetchmail的配置文件为~/.fetchmailrc。然后文件权限最少要设置chmod 600 ~/.fetchmailrc

比如我们要设置多个邮箱账户同时收取,那么配置如下:

poll pop.AAA.com protocol POP3 user "me@AAA.com" password "123"

poll pop.BBB.com protocol POP3 user "me" there with password "123" is falko here fetchall

poll pop.CCC.com protocol POP3 user "me" there with password "123" is till here keep

poll pop.DDD.com
  protocol POP3
  user "me"
  password "123"

## QQ 邮箱
poll pop.qq.com
  port 995 
  protocol POP3
  user "1664548605@qq.com"
  password [授权码]
  ssl
  keep

# 全局选项
mimedecode
# 不加 -d %T 就会报 ~/Mail/inbox is not a mailbox. 错误
mda "/usr/bin/procmail -d %T"

其中:

  • 各种参数可以不按顺序,也可以不在一行。 空格隔开每个参数,poll隔开每个账户。
  • here, there, with, is等等,都不是关键词,随便写不影响参数。
  • 以下是必填
    • poll后面是邮件服务器的地址,一般是pop.xxx.com
    • protocol后面是收件协议,一般是poppop3
    • user后面是用户名,可以是username,也可以是邮箱地址
    • password后面是密码
  • sslproto:可能会报错 fetchmail: pop.qq.com: upgrade to TLS failed.,故可以禁掉SSL,同 man 手册查到
    • 加上option --nosslcertck,虽然有报错,但至少可以收邮件了。
    • --sslprotocl '', 注意要用空字符串
  • 四选一:
    • nofetchall :仅检索新消息(默认)。
    • fetchall :获取所有消息,无论是否看到。
    • keep :不要从服务器上删除看到的消息。
    • nokeep :从服务器中删除看到的消息。
  • mimedecode用来自动解码MIME
  • mda后面指定本机安装的邮件过滤分类程序。如果不填,则收取的邮件在本地不会保存。注意用which procmail查一下路径。
  • Outlook 邮件客户端设置
  • Gmail 邮件客户端设置
  • QQ 邮件客户端设置
  • 163 邮件客户端设置

配置完成后,可以运行fetcmail -v来看看是否有错误信息,如果能够正常显示很多行的收取信息,那么就能正确登录邮箱收取了。

一般收取的命令如下:

# 只收取未读邮件
$ fetchmai

# 收取所有邮件
$ fetchmail -a

# (重要)收取新邮件,但不在服务器端删除已经收取的邮件
$ fetchmail -k

但是fetchmail只负责收取,不负责“下载”部分,你找不到邮件存在哪了。 所以还需要配置MDA分类器,如procmail,才能看到下载后的邮件。

注意:Fetch其实不是在Mutt“里”使用的,而是脱离mutt之外的!也就是说,Mutt只负责读取本地存储邮件的文件夹更新,而不会自动帮你去执行fetchmail命令。

你必须自己手动执行,或者用Crontab定期收取,或者设为Daemon守护进程,还可以在Mutt中设置快捷键执行Shell命令:

  • 要使fetchmail作为守护进程运行,我们必须编辑/etc/default/fetchmail并将START_DAEMON设置为yes

    $ vi /etc/default/fetchmail
    START_DAEMON=yes
    

    xxxxxxxxxx yum -y install tigervnc-servershell

  • 设置Mutt快捷键收取邮件的方法是在~/.muttrc中加入macro:

    macro index,pager I '<shell-escape> fetchmail -vk<enter>'
    

    这样的话,你就可以在index邮件列表中按I执行外部shell命令收取邮件了。

邮件过滤:配置Procmail

Procmail是单纯负责邮件的存储、过滤和分类的,一般配合fetchmail收件使用。

在Pipline中,fetchmail把收到的邮件全部传送到Procmail进行过滤筛选处理,然后Procmail就会把邮件存到本地形成文件,然后给邮件分类为工作、生活、重要、垃圾等。

当然,分类规则是自己可以指定的。可以根据发信人、主题、长度以及关键字 等对邮件进行排序、分类、整理。

Procmail 的配置文件是 ~/.procmailrc ,记得改权限:chmod 600 ~/.procmailrc

内容也非常简单,前面是邮件位置、日志等默认选项,后面则是一块一块的过滤规则。

基本配置:

# 邮件存储地址
MAILDIR=$HOME/Mail   
# 默认:收件箱
DEFAULT=$MAILDIR/inbox   
VERBOSE=off
LOGFILE=/tmp/procmaillog

# 某个垃圾邮件规则
:0
* ^From: webmaster@st\.zju\.edu\.cn
# 垃圾文件的存储位置
/dev/null    

# 其它所有都存到收件箱中
:0:
inbox/

其中,$HOME/Mail是设定的邮件存储位置。

我们需要手动创建mkdir ~/Mail,否则程序会报错。

配置好后,我们再测试一下就会看到:

$ fetchmail -a
78 messages for 1664548605@qq.com at pop.qq.com (2843793 octets).
reading message 1664548605@qq.com@pop.qq.com:1 of 78 (36692 octets) not flushed
...

$ tree ~/Mail
/home/vane/Mail
└── inbox

0 directories, 1 file

$ du -h Mail/inbox 
2.1M    Mail/inbox

可以看到,所有邮件都保存在了inbox这个单一文件中。这个文件可以打开看到MIME格式(协议)的邮件源码。就像HTML一样,展示给我们的和背后的源码不一样。

那么怎么把这个类似HTML的MIME格式邮件解析为我们人能读懂的内容呢?——这个我们就要靠mutt自己了,mutt自身具备基本的MIME邮件解析功能(不包括HTML格式邮件读取)。

发件:配置msmtp

msmtp是作为sendmail发邮件程序更好的替代品。

msmtp的配置文件为~/.msmtprc,记得改权限:chmod 600 ~/.msmtprc

配置内容比收件还简单,因为发件永远比收件简单。

基本配置:

account default
  auth login
  host smtp.XXX.com
  port 587
  from ME@XXX.com
  user ME
  password passwd
  # 关于tls,如果是阿里云则不用写,如果是Outlook的话,必须写
  tls on
  tls_starttls off
  tls_certcheck off

# QQ 邮箱例子
account default
  # QQ邮箱这里必须是 on,否则会 535 Login Fail
  auth on
  host smtp.qq.com
  port 587
  from 1664548605@qq.com
  # user 必须是 @ 之前的部分,不能自定义,否则会 535 Login Fail
  user 1664548605
  password [授权码]
  tls on
  tls_starttls off
  tls_certcheck off

logfile /tmp/msmtp.log

QQ 邮箱例子:使用mutt+msmtp在Linux命令行界面下发邮件

总之,哪怕QQ 邮箱设置对了,也要多试几次才能发送成功。

主界面:配置Mutt

Mutt的配置文件为~/.muttrc,记得改权限:chmod 600 ~/.muttrc

另外:mutt的配置文件还可以放在~/.mutt/muttrc。这种方法有一个好处,即~/.mutt/目录下可以放很多主题、插件等文件。

基本配置:

# 通用设定
set use_from=yes
set envelope_from=yes
#移动已读邮件
set move=yes    
#回复的时候调用原文
set include 
set charset="utf-8"
#自动显示HTML
auto_view text/html   

# 发送者账号
set realname="Vane Hsiung"
set from="1664548605@qq.com"

# 分类邮箱
#Mail box type
set mbox_type = Maildir 
set folder = "$HOME/Mail"
#INBOX
set spoolfile = "$HOME/Mail/inbox" 
#Seen box
set mbox="$HOME/Mail/seen" 
#Sent box
set record="$HOME/Mail/sent"  
#Draft box
set postponed="$HOME/Mail/draft"  

# 关联程序(需要自己用which命令确定一下)
# 默认使用 nano
set editor="vim"
set sendmail="/usr/bin/msmtp"

以上如果有什么问题,可参考etchmail + proc + msmtp + mutt configuration samples

确认邮箱服务器

即使上面配置一切OK,也不一定能正常收发邮件。因为你用的Gmail、QQ、网易、阿里云等等,后台都有一系列的第三方收取设置。这是各不相同的。

除了第三方客户端的允许,我们还要设置POP。最好放开全部邮件或者最近30天,然后禁止客户端删信。这是什么意思呢?POP默认客户端在收件后,服务器上的邮件就自动删除了!这个不太合适,所以必须要禁止。

基本操作

邮件列表操作:

  • 基本:q:Quit, d:删除当前邮件, s:将邮件移动至指定文件夹, m:创建新邮件, r:回复当前邮件, ?:帮助
  • 移动:j/k 上下移动邮件, z/Z上下翻页, <Number> 跳至序号处(不进入邮件)
  • <Enter> 打开选中的邮件
  • /在当前文件夹搜索
  • d 将选中邮件标记为删除, N 将选中邮件标记为未读, $ 让标记的东西生效,如删除、未读等。
  • f 转发选中邮件, e 编辑选中邮件
  • c切换文件夹(inbox/seen/draft等), 需要输入文件夹名称,或按?在列表里选择,j/k上下移动。

在邮件中的操作:

  • j/k 上一封/下一封邮件, <Space>: 向下翻页, <Enter>: 向下滚动
  • e 编辑当前邮件, t编辑TO,c编辑CC,b编辑BCC,y发送邮件,a添加附件,Return查看附件,E编辑附件,D删除附件

使用命令操作

Mutt如同Vim一样,不光可以把命令绑定为快捷键,还能直接输入:直接输入命令。 但是稍有不同的是,Mutt称之为Action,而且需要用:exec <命令>这样格式执行。

比如sidebar侧边栏的移动,命令是:sidebar-next, sidebar-prev。 那么我们可以直接输入:exec sidebar-next,按下回车执行。

IRC

简介

芬兰人雅尔可·欧伊卡利宁(Jarkko Oikarinen)于1988年8月创造了IRC来取代一个叫做MUT的程序。

  • IRC(Internet Relay Chat的缩写,“因特网中继聊天”)是一个位于应用层的协议。
  • 其主要用于群体聊天,但同样也可以用于个人对个人的聊天。
  • 一个IRC服务器可以连接其他的IRC服务器以扩展为一个IRC网络。
  • IRC 不强制注册;但如果你注册了,就可以强制把占用自己唯一 ID 的人踢下线。
  • IRC 协议简单,开源实现多,其第三方机器人程序非常众多,几乎每种语言都有一个实现。
  • IRC 是开源社区会议标准;因此,许多开源世界的技术大牛混在那里。

irchelp:一个致力于帮助用户了解IRC的网站。

IRC:Linux文档项目的IRC HOWTO

服务器

首先要区分一些概念:

  • Networks:是指的互相隔离的网络,如Libera.Chat和DALnet这些是世界知名的网络,但互相隔离,频道不共享。
  • Servers:Network网络中的某一台电脑服务器,你加入世界上任何一个server都能加入这个Network。IRC是一个分布式的客户端/服务器结构。通过连接到一个IRC服务器,我们可以访问这个服务器以及它所连接的其他服务器上的频道(即这个 Network 中所有频道)。

频道存在于一个IRC服务器上。一个频道类似于一个聊天室,频道名称必须以#符号开始,例如#irchelp

要使用IRC,必须先登录到一个IRC服务器上,Libera.Chat为免费和开源软件社区,非营利组织和相关社区提供讨论设施。(在Freenode被安德鲁·李接管后,Freenode的前成员创办了Freenode的替代服务Libera Chat。)

IRC使用的服务器端口有:

  • 6667(明文传输)
  • 6697(SSL加密传输,如ircs://irc.libera.chat:6697)。

IRCD: 简称互联网中继聊天守护,是服务器软件实现了IRC 协议,使人们通过上网彼此交谈(交换文本即时消息)。

客户端

IRC用户透过客户端软件和服务器相连。

常用客户端:

Client Homepage 描述
HexChat https://hexchat.github.io/ 基于XChat的图形化IRC客户端。
Irssi https://irssi.org/ 支持IPv6的模块化文本UI IRC客户端。
Pidgin https://pidgin.im/ 具有GTK +界面的流行即时消息客户端。
WeeChat https://weechat.org/ 便携式和多接口(文本,Web和GUI)IRC客户端。
Konversation https://konversation.kde.org/ 基于KDE框架的用户友好型IRC客户端。
Polari https://wiki.gnome.org/Apps/Polari GNOME的IRC客户端
ircii http://eterna.com.au/ircii/ 在大多数UNIX平台下运行的IRC和ICB客户端。
kvirc http://www.kvirc.net/ 使用Qt GUI工具包的便携式IRC客户端。
Quassel https://quassel-irc.org/ Qt5 IRC客户端支持远程守护进程以实现全天候连接

Irssi

安装

apt install irssi

命令行输入irssi即进入了聊天室。

和一般Linux程序的一般命令、格式都不同,IRC客户端一般有自己的命令。窗口右下方[(status)]是输入命令的地方。

一般命令(不区分大小写):

  • /quit,退出程序。一般的ctrl-c, ctrl-d, esc, q之类的都不管用
  • /help,帮助
  • /network list 查看已保存的服务器列表
  • /connect xxx.xxx.xxx 连接某服务器。
  • /join xxx 加入某channel
  • /leave/part 离开当前channel
  • /normal/n 查看当前channel的人数
  • /list -YES 查看当前服务器的所有chennels (慎用)
  • /nick NewNickName 更改当前昵称
  • /msg NickName Content 给某人发送消息,一般都是给/msg nickserv管理人NPC发送消息

常用快捷键:

  • Alt + 1/2/3/4...,切换window窗口,一般一个channel一个窗口
  • Alt + n/p,上下滚动屏幕

IRC 常用缩写词

配置

如果想长期保存、备份一个固定的程序配置,那么就需要修改配置文件。

irssi默认的配置文件为~/.irssi/config

配置中,会在第一次运行时就自动设置了一些,包括根据当前电脑账户的用户名设置nickname等。整个配置,是一直“类似”JSON的格式。

settings :记录自己的名字:nick, real_name, user_name

servers :这是指的Network而不是具体某台server,如Freenode、Dal、ESPer、EFnet等大型网络。服务器配置案例:

servers = (
  { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; },
  {
      address = "路径";
      chatnet = "下面chatnet对应的名称";
      port = "端口";
      autoconnect = true;
      use_ssl = "yes";
      password = "用户名:密码";
  }
);

chatnets:记录各个网络的登录信息,也可以作为“别名”,这样每次/connect不用输入全路径了。配置完每个服务器后,还要配置相应的chatnets,每一条的名称都要与servers中的对应。

chatnets = {
    DALnet = {
        type = "IRC";
        max_kicks = "4"; max_msgs = "20";max_whois = "30";
    };
    Freenode = {
        type = "IRC";
        max_kicks = "4"; max_msgs = "20";max_whois = "30";
        autosendcmd = "/msg nickserv identify MyName MyPassword";
    };
};

channels :记录自己收藏的频道名。RC的频道不是用URL之类很复杂的东西,全都是用#tag这种简单一个标签来区分的,非常好记。

channels = (
  { name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; },
  { name = "#freenode"; chatnet = "Freenode"; autojoin = "No"; },
);

statusbar:界面美化的设置。目前IRSSI的世界里,唯一知名的主题只有weed

Multimedia

GStreamer

GStreamer 入门概念

Overview

GStreamer是一个多媒体框架,它可以允许你轻易地创建、编辑与播放多媒体文件,这是 通过创建带有很多特殊的多媒体元素的管道来完成的。

管道-pipeline

GStreamer的工作方式非常简单,你只需创建一个包含很多元素的管道,这与Linux命令行 的管道非常类似,例如,一般命令行的管道是这样的:

ps ax | grep "apache" | wc -l

这个命令首先捕获一个进程列表然后返回名字包含 “apache” 的进程并传递给 wc 命令并 统计出行数。我们可以看出每一个使用 | 连接,并且 | 左边的命令的输出传递 给其右边的命令作为输入。

GStreamer的工作方式与此类似,GStreamer中你将很多元素串联起来,每一个元素都完成 某些特定的事。我们来演示一下:

gst-launch-1.0 filesrc location=越单纯越幸福.mp3 ! decodebin ! audioconvert ! alsasink

运行这条命令你就可以听到动听的音乐了,当然前提是你的当前目录有这个音乐文件。

gst-launch-1.0 可以用来运行 GStreamer 管道,你只需要将需要使用的元素一个一个 传递给它就可以了,每一个命令使用 ! 来连接。此处你可以把 ! 当作命令行里 的 | 。上面那条命令包含了几个元素,我们简单解释一下:

  1. filesrc:这个元素从本地磁盘加载了一个文件,使用该元素时你设置了 location 属性指向了音乐文件,关于属性我们后边聊。
  2. decodebin:我们需要从 filesrc 解码,因此我们使用了这个元素。这个元素是一个 聪明的小家伙,它会自动检测文件的类型并在后台构造一些GStreamer元素来解码。因此, 此处对于 mp3 你可以使用 mad 代替之试一下。
  3. audioconvert:一个声音文件中有各种各样的信息,每种信息传递到喇叭都是不同的, 因此要使用此元素来做一下转换。
  4. alsasink:这个元素做的事很简单,就是把你的音频使用ALSA传递给你的声卡。

文章写到这里,我们就可以使用管道来做各种试验了,但首先我们要知道有那些元素可以 使用啊:

gst-inspect-1.0

这个命令列出了可用的元素,你也可以使用该命令查看某一元素的详细信息,例如 filesrc 元素:

gst-inspect-1.0 filesrc

下面介绍一些GStreamer的相关术语,一些人可能很快就会对 pad, cap 这些术语搞晕, 就不要说 binghost pad 了。其实这些术语都相当的简单。。。

元素element

其实我们已经讨论了管道,而元素就在管道上。每一个元素都有很多属性用来设置该元素。 例如, volume 元素(设置管道的音量)有一个熟悉 volume 可以设置音量或者静音。 当你创建自己的管道时就要给很多的元素设置属性。

pad

每一个元素都有虚拟的插头供数据流入和流出,即pad。如果你把元素看作一个对输入的 数据做一些处理的黑盒。在盒子的左右两边就是插孔了,你可以插入电缆向盒子传入信息, 这就是pad要做的事。绝大多数元素有一个输入pad(叫做sink)和一个输出pad(叫做src)。 因此,我们上面的管道看起来是这样的:

[src] ! [sink src] ! [sink src] ! [sink]

最左边的元素只有一个src pad用来提供信息(如filesrc)。接下来的几个元素接收信息并 做一些处理,因此他们有sink和src pad(例如decodebin和audiocovert),最后一个元素 只接收信息(例如alsasink)。当你使用 gst-inspect-1.0 命令查看一个元素的详细 信息时,就会列出该元素的pad信息。

注意可能与平时大家认为的概念有些不同的是,src pad是用来发送数据的端点,即数据的 输出端;而sink pad是用来接收数据的端点,即数据的输入端。

而且,一般来说,src pad只能连接到sink pad。当然,没有例外的规则是不存在的, ghost pad两端就要连接相同类型的pad,具体请参考后面的例子吧。

cap

我们已经了解了pad和从管道第一个元素到最后一个元素的数据流是怎么回事了,那么我们 来讨论下 cap 。每一个元素都有特定的cap,cap是指该元素可以接收什么样的信息( 例如是接收音频还是视频)。你可以把cap看成是电源插座上其可以接受什么范围电压的规则。

bin

很多人不理解bin,其实它很简单。bin就是一种便捷的方式,可以把很多个元素放进一个 容器中。例如你有很多个元素用来解码视频并对其使用一些效果。要使事情变得简单一些, 你可以把这些元素放进一个bin(就像一个容器)中,以后你就可以使用bin来引用这些元素了。 这样其实bin变成了一个元素,例如你的管道是 a ! b ! c ! d ,你可以把他们放进 mybin,这样当你使用mybin时其实是引用了 a ! b ! c ! d

ghost pad

当你创建了一个bin并在里面放置了很多元素时,该bin变成了你自定义的元素,该元素按 顺序调用里面的元素。要做到这样,你的bin很自然地需要它自己的pad,它自己的pad会挂接 到bin里面元素的pad上,这就是 ghost pad 了。当你创建一个bin时,你创建了ghost pad 并告诉他们要去挂接里面哪一个元素。

GStreamer 系列

FFmpeg

  • powershell 执行与在 cmd 执行不一样,poweshell 某些 -c:v 会报错
  • ffmpeg 输出参数含义
    • frame: 编码的帧数量
    • fps:每秒编码的帧数
    • q:质量因子
    • size/ Lsize:视频和音频编码后的大小,即基本等于视频和音频 之和
    • time:输出帧的显示时间
    • bitrate:输出视频的比特率
    • dup:输入帧重复(duplicate)的数量
    • drop:输入帧丢弃(drop)的个数
    • speed:编码速度

视频文件本身其实是一个容器(container),里面包括了视频和音频,也可能有字幕等其他内容。

视频和音频都需要经过编码,才能保存成文件。不同的编码格式(CODEC),有不同的压缩率,会导致文件大小和清晰度的差异。

编码器(encoders)是实现某种编码格式的库文件。只有安装了某种格式的编码器,才能实现该格式视频/音频的编码和解码。

FFmpeg 的命令行参数非常多,可以分成五个部分:

ffmpeg [全局参数] [输入文件参数] -i 输入文件 [输出文件参数] [输出文件]

常用参数

  • -c:指定编码器
  • -c copy:直接复制,不经过重新编码(这样比较快)
  • -c:v:指定视频编码器
  • -c:a:指定音频编码器
  • -i:指定输入文件
  • -an:去除音频流
  • -vn: 去除视频流
  • -preset:指定输出的视频质量,会影响文件的生成速度,有以下几个可用的值 ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow。
  • -y:不经过确认,输出时直接覆盖同名文件。

查看视频文件的元信息

ffmpeg -i input.mp4 -hide_banner

转换编码格式

ffmpeg -i [input.file] -c:v libx264 output.mp4

转成 H.264 编码,一般使用编码器 libx264

转换容器格式

ffmpeg -i input.mp4 -c copy output.mkv

改变分辨率

ffmpeg -i input.mp4 -vf scale=720:-1 output.mp4

提取视频

ffmpeg -i input.mp4 -an -c:v copy ouput.mp4

-vcodec codec 强制使用codec编解码方式。如果用copy表示原始编解码数据必须被拷贝。

提取音频

ffmpeg -i input.mp4 -vn -c:a copy output.aac

-c:a copy表示不改变音频编码,直接拷贝。

添加音轨

ffmpeg -i input.aac -i input.mp4 output.mp4

音视频合成

ffmpeg -i video.mp4 -i audio.aac -c:v copy -c:a copy output.mp4

截图

从指定时间开始,连续对1秒钟的视频进行截图

ffmpeg -y -i input.mp4 -ss 00:01:24 -t 00:00:01 output_%3d.jpg

指定只截取一帧

ffmpeg -ss 01:23:45 -i input.mp4 -vframes 1 -q:v 2 output.jpg

-vframes 1指定只截取一帧,-q:v 2表示输出的图片质量,一般是1到5之间(1 为质量最高)。

裁剪

ffmpeg -ss [start] -i [input] -t [duration] -c copy [output]
ffmpeg -ss [start] -i [input] -to [end] -c copy [output]

裁剪(cutting)指的是,截取原始视频里面的一个片段,输出为一个新视频。可以指定开始时间(start)和持续时间(duration),也可以指定结束时间(end)。

添加字幕

  • 外挂字幕:一个单独的外部字幕文件,格式类型一般有srt、vtt、ass等等。播放视频时,需要把外挂字幕和视频放在同一目录下,并在播放器中选择字幕文件才可以在视频中看到字幕。
  • 软字幕:也叫内挂字幕、封装字幕、内封字幕,字幕流等,就是把前面的外挂字幕的字幕文件嵌入到视频中作为流的一部分,如果一个视频有多个字幕流那么播放视频是还得选择对应的字幕流
  • 硬字幕:是嵌入到视频帧里面的字幕,它就像视频水印一样作为视频帧的一分部分了,不管再任何平台字幕看起来都是一样的,而且也不再要求播放器单独对字母进行渲染

常见的字幕格式有:

  • SRT(标准外挂字幕格式):只包含文字和时间码,没有样式,显示效果由播放器决定,不同的播放器显示出的效果可能差别很大。
  • ASS(高级外挂字幕格式):支持样式、字体、字幕定位、淡入淡出、简单的特效。如果不缺字体,不同的播放器显示效果基本一致。

ffmpeg字幕处理流程(容器是否支持字幕流指的是输出容器)

添加软字幕:

ffmpeg -i video.mp4 -i subtitle.srt -c copy output.mkv

软字幕只有部分容器格式比如(mkv)才支持,MP4/MOV等不支持,而且也只有部分播放器支持软字幕或者外挂字幕(如VLC播放器)。

添加多个字幕:

ffmpeg -i input.mp4 -i zh_CN.srt -i en_US.srt -map 0:v -map 0:a -map 1 -map 2  -c:v copy -c:a copy -metadata:s:s:0 language=chn -metadata:s:s:1 language=eng "output.mp4"
  • -map 是轨道参数,如果只有一个字幕,就不需要这个参数。-map 0:v 表示第一个文件输入视频轨道,-map 0:a 表示第二个轨道是第一个文件输入的音频轨道,-map 1 建立第三个轨道,-map 2 建立第四个轨道。如果没添加 map 参数,默认就只有一个字幕轨道,第二个英文字幕会覆盖第一个中文字幕轨道。
  • -metadata:s:s:0 language=chn 第一条字幕的语言设置为中文,-metadata:s:s:1 language=eng 第二条字幕的语言设置为英文。 language 不能自定义,只能设置成固定的缩写。

添加硬字幕:

ffmpeg -i video.mkv -vf subtitles=subtitle.srt out.mp4

下载 m3u8

现在比较常见的视频流媒体,大部分都是 m3u8 格式的,而对于 m3u8 格式的视频而言,如果你下载过,你会发现它就是一个文本文件,大概也就只有几十 kb,从磁盘大小来看,应该也知道它并不是一个直接的视频文件。

什么是 m3u8

说到 m3u8 就要先说说 HLS(HTTP Live Streaming)。HLS 是 Apple 公司针对 iPhone、iPod、iTouch 等移动设备,而研发的基于 HTTP 协议的流媒体解决方案。在 HLS 技术中,Web 服务器可以向客户端提供接近实时的音视频流,但是它又是使用的标准的 HTTP 协议。所以基本上,比较大型的点播直播类服务,都是基于 HLS 的。

而该技术的原理,就是将视频文件或者视频流,进行切片(ts文件),并建立索引文件(m3u8),它支持的视频流编码为 H.264,音频流编码为 AAC。

简单来说,基于 HLS 的视频流,会将完整的视频,切割成一个个比较小的视频片段(ts 文件),然后根据协议组合成一个 m3u8 文件。这些比较小的 ts 文件,是可以单独播放的。而视频播放器,拿到 m3u8 文件之后,根据对其内 ts 片段的索引,连续播放不同的视频片段,来达到流畅的播放效果。

下载的 m3u8 文件

说这些概念都没用,我们来看两个真实的被下载的 m3u8 文件。

img

这种 m3u8 文件就还是比较清晰的,能看到它一个个的片段。但是需要注意的是,这里的片段,全部是基于域名的相对地址,也就是说,这样一个 m3u8 文件,你丢到播放器里,是无法播放的,但是如果你记录了原始下载这个 m3u8 的链接,它在播放器里是可以正常播放的。

当然,如果你修改这个 m3u8 文件,将它相对路径拼接上域名地址,也是可以达到播放的效果的。

再来看看另外一种 m3u8 文件,它其内的 ts 片段,都是完整地址。

img

像这种具有完整地址的 ts 片段,哪怕你将它保存成一个本地的文件,播放器依然是可以直接播放的,不过这里本质上依然是在在线播放。

这两中 m3u8 文件,虽然有细微的差别,但是它们都是基于标准的协议。

简单总结一下:

  1. m3u8 不是视频内容的文件,它占用的磁盘空间非常的小。
  2. m3u8 文件,如果其内的 ts 片段,是完整地址,则可以保存后播放,否者只能在线播放。
  3. 播放器播放 m3u8 文件的时候,实际上,还是在线从线上获取的视频流进行播放,所以是存在失效的情况的。

暂时知道这三点就可以了,接下来我们再看如何将一个 m3u8 文件,下载成一个 mp4 视频文件。

使用 fmpeg 下载 m3u8

ffmpeg 是一套可以用来记录、转换音视频,并将其转化为流的开源程序,采用 LGPL 或 GPL 协议许可证书,很多大型的音视频软件,内部都是基于 ffmpeg 的。

ffmpeg -i "m3u8_file_uri" "save_video.mp4" 

到此,如果 m3u8 的链接正确可播放,就会开始下载,等待下载完成就可以了,最终会在指定目录下,保存 save_video.mp4 文件,它就是最终我们下载的离线视频文件。

blob url

想下载淘宝上一个视频,打开控制台审查元素定位到video标签发现视频地址是blob:https开头,不能直接下载,可能是网站为了防止下载使用这种方式做了保护,用这种的大部分原始视频都是m3u8格式。

获取blob真实地址:控制台单击network filter里输入.m3u8 刷新浏览器重新拉取资源,出现的就是m3u8地址,把他复制下来用 ffmpeg 下载就可以了

webm to gif

ffmpeg -i input.webm -pix_fmt rgb8 output.gif

MKVToolNix

MKVToolNix is a set of tools to create, alter and inspect Matroska(mkv) files under Linux, other Unices and Windows.

轨道提取模式:

mkvextract 输入文件名 tracks [选项] TID1:目标文件名1 [TID2:目标文件名2 ...]

TID:输出文件名 如果输入文件中存在 ID 为 TID 的轨道,则将其提取为文件 输出文件名。轨道 ID 与 mkvmerge --identify 文件 选项所输出的相同。

mkvextract "Another Movie.mkv" tracks 0:video.h265 "1:main audio.aac"

Rhythmbox

Music

搜 “无损音乐” “车载音乐” 打包下载。

將音樂從計算機上的文件夾導入

為了使用Rhythmbox,您需要創建一個音樂庫。要做到這一點,請點擊“導入”按鈕。點擊“選擇位置”下拉菜單,然後在計算機上選擇一個包含音樂的文件夾。

Prodcast/播客

通过 feed 链接订阅,查看播客 Feed 订阅

喜马拉雅的播客feed是 https://www.ximalaya.com/album/[ID].xml,即在播客url后添加.xml就行,但是只限于免费的。

Radio/电台

互聯網廣播

廣播電台列表將出現在Ambient到Underground的各種類別中。 選擇您想收聽的電台並點擊播放圖標。

如果您希望收聽的廣播電台沒有出現,請點擊“添加”並輸入廣播電台供稿的URL。

其他收听方式

一种方式是通过传统的无线电收音机收听,一般手机上带有 Radio 软件,需插上有线耳机才能收听。

另一种方式是通过各种平台收听,例如喜马拉雅、蜻蜓FM、央广的云听等,这种收听方式可以在浏览器 DevTool 中得 Network 栏中获取播放链接。

电台推荐

中國電台直播源列表

中國國際廣播電台(CRI)

中國中央人民廣播電台(CNR)

香港电台(RTHK)

其他直播源

International

相关资源

2009年旧方法

很多电台是基于Microsoft Media Server (MMS) streaming protocol的,如果rhythmbox无法播放mms协议的电台,则需要安装支持mms协议的gstreamer插件——因为rhymbox使用gstreamer做后台解码。支持mms协议的插件为gstreamer-bad插件,所以执行命令:

sudo apt-get install gstreamer0.10-plugins-bad

同样的,如果需要播放mp3文件则安装ugly插件,需要播放wma文件则安装ffmpeg插件。

播客和电台

  • 播客和电台的区别是什么?

播客和电台的区别比较明显,一句话概括:播客是通过互联网承载的声音内容;电台则通过传统的广告媒介运营,现在也在互联网上分发拷贝。

播客,中文圈对“Podcast”的翻译,而Podcast是苹果公司的产品,是由“iPod”和“broadcast”(广播)的混成词,将数码产品和内容产品合二为一。Podcast和itunes一样都对声音内容的生产和商业化产生了深远影响。

电台,准确来讲是指电台广播(Radio broadcasting),和苹果公司的定义相比,那就是不需要通过他家“iPod”就可以听的广播咯。

  • 为什么现在的平台上(例如喜马拉雅、网易云音乐)都把播客划分为电台?

最核心的原因是,现在国内大的声音内容服务平台,声音内容是极其丰富的,例如直播、录播、有声书……(儿童、历史的分类法是按题材/内容划分)从节目录制和播放形式上来看,电台和播客本来都属广播(broadcasting),自然被放到一起了。

另外,独立播客的的分发方式是在服务器中把一系列的音频档通过RSS消息来源列出,你可以通过任意一种泛用性podcast工具进行RSS订阅收听。现在也仍然有很多泛用性podcast平台提供类似服务,而国内的声音内容平台例如喜马,荔枝也为播客主提供托管服务,但更多是一种延伸服务,显然不是主打。

最后,播客之所以往往是在各个频道里跟其他内容混装在一起,是因为播客主按自己节目内容类型进行分类,被归入了各个频道。比如我们做的[2082FM]选择的类型标签是“文化”,其实我挺没文化的。

Missing plugin

Rhythmbox-Message: 16:22:38.404: Missing plugin: gstreamer|1.0|rhythmbox|application/x-hls decoder|decoder-application/x-hls

解决方法:The element missing is named hlsdemux and lives in gst-plugins-bad.

sudo apt install gstreamer1.0-plugins-bad

所有 GStreamer Plugins

FeelUOwn

FeelUOwn 是一个稳定、用户友好以及高度可定制的音乐播放器。支持全平台。

Clementine

Clementine is a modern music player and library organizer for Windows, Linux and macOS.

image-20220719203631775

cmus

Small, fast and powerful console music player for Unix-like operating systems.

官方教程翻译版

DeaDBeeF

DeaDBeeF (as in 0xDEADBEEF) is a modular cross-platform audio player which runs on GNU/Linux distributions, macOS, Windows, *BSD, OpenSolaris, and other UNIX-like systems.

jellyfin

The Free Software Media System

Audacious

Audacious is an open source audio player.

KDE elisa/amarok

elisa: Simple music player aiming to provide a nice experience for its users

amarok: Powerful music player that lets you rediscover your music

Elisa 在播放文件不可用的时候会迅速的删光所有歌曲,它的播放列表经常被破坏

osdlyrics

Standalone lyrics fetcher/displayer (windowed and OSD mode).

ZonyLrcToolsX

ZonyLrcToolsX 是一个能够方便地下载歌词的小软件。(ps:一点也不见得方便)

NeteaseMusic

Linux 下官方只发布了 deb 包,flatpak 直接安装

YesPlayMusic

高颜值的第三方网易云播放器

NetEase-MusicBox

网易云音乐命令行版

lx-music-desktop

一个基于 electron 的音乐软件

listen1_desktop

one for all free music in china

QQMusic

Spotify

作为世界上最大的音乐流媒体服务商,Spotify 因优秀的设计和精准的音乐推荐算法让不少人为之倾心。

在正式注册 Spotify 之前,我们先来看一看曲库的问题。由于不同地区的歌曲版权差异,Spotify 在不同地区提供服务时,其相应的曲库也有所不同。例如港区的曲库中,粤语歌就要比美区多,相反美区的英文歌就要比港区多。同理,若你喜欢听其他语种的歌,注册当地的 Spotify 则是最好的选择。

注册后要是发现当前的地区选择并不是很理想,想要换区也是可行的。首先要挂上自己想要换到地区的代理,然后进入自己的「Profile/资料」界面,点击「Edit Profile/修改资料」,「Country/国家」这个选项就会出现你当前所挂代理地区,保存更改即可换区成功。

登录的话,需要先在登录界面设置Proxy重启。登录后在设置里改回来,不再需要Proxy了。

Spotifyd

An open source Spotify client running as a UNIX daemon.

MPV

MPV 是基于 MPlayer 和 mplayer2 的开源极简全能播放器。支持各种视频格式、音频解码、支持特效字幕(电影动漫的ass特效字幕都没啥问题),不仅支持本地播放,同样支持网络播放(mpv 集成了 youtube-dl)。重点是 MPV 具有多系统平台支持、命令行、自定义、GPU 解码、脚本支持等特点……

更多请阅读官方参考手册,及其中文版

快捷键

虽然 MPV 并没有提供官方的 GUI 界面,没有菜单,但它提供 OSC 操作界面和快捷键用于操作,只要关联好文件格式,使用 mpv 打开视频后,使用上其实也非常的简单方便。

鼠标操作

快捷键 作用说明
鼠标左键双击 进入/退出全屏
鼠标右键单击 暂停/继续播放
鼠标滚轮 快进/快退

播放控制

快捷键 作用说明
p Space 暂停、继续播放
/ * 减少/增加音量
9 0 减少/增加音量(数字键盘区的9、0不可用)
m 静音
快退/快进5秒
快进/快退1分钟
< > 上一个/下一个(播放列表中)
Enter 下一个(播放列表中)
F8 播放列表
l 设定/清除 A-B循环点
L 循环播放
s 截屏
q 停止播放并退出
Q 保存当前播放进度并退出,播放同样文件从上次保存进度继续播放。

视频控制

快捷键 作用说明
_(下划线) 循环切换可用视频轨
A 循环切换视频画面比例
Alt+0 0.5倍源视频画面大小
Alt+1 1倍源视频画面大小
Alt+2 2倍源视频画面大小
Ctrl+h 在运行时切换硬解码。它在 autono 之间切换这个选项。

音频控制

快捷键 作用说明
# 循环切换可用音频轨
Ctrl + Ctrl - 音轨延迟+/- 0.1秒

字幕控制

快捷键 作用说明
V 关闭/开启字幕
j J 循环切换可用字幕轨
x z 字幕延迟 +/- 0.1秒
r t 上移/下移字幕位置

窗口控制

快捷键 作用说明
T 窗口始终置顶
f 进入/退出全屏
ESC 退出全屏

配置

因为mpv本身不具有图形化前端,绝大多数的设置选项都是靠在主设置文件 ~/.config/mpv/mpv.conf 中输入参数实现的。可以参考 官方的内建方案懒人包版

## 基本说明:
## 注释内容解释 —— # <可选值> [条件要求] 参数意义说明 (补充)
## 部分选项之间有关联作用,MPV读取参数时由上往下读,所以注意书写通用参数的顺序

# 追加读取额外的设置文件,在默认设置文件之后进行解析。
# ~~ 意思是 mpv config dir,例如 ~/.config/mpv/
# include="~~/profiles.conf"  

# 在将要播放的文件的同一目录下查找针对该文件的设置文件
use-filedir-conf=yes 

# 打开给定的路径进行写入,并输出日志信息到其中。
# ~~desktop 是桌面
# log-file="~~desktop/mpv.log" 
log-file="~~/mpv.log" 

########
# 基础 #
########

# 指定一个要使用的视频输出驱动的优先级列表。
# gpu 通用的可定制的、GPU加速的视频输出驱动。
# gpu-next 基于 libplacebo 的实验性视频渲染器。它几乎支持与 gpu 相同的功能集。
# 许多渲染相关的选项也只能在这两项下正常工作。首选gpu。
vo=gpu 

# 选择用于FBOs的纹理的内部格式。该格式可以影响视频输出的性能和质量。
fbo-format=auto      

# 如果可能的话,指定应该使用的视频硬件解码API。
# 硬解码是否实际完成取决于视频编码。如果硬件解码不可能,mpv将回退到软件解码。
# 如果希望硬件解码在默认情况下被启用,可以使用 auto-safe 
hwdec=auto-safe

# 只允许对一个给定的编码列表进行硬件解码。特殊值 all 总是允许所有的编码。
# 默认情况下,这被设置为 h264,vc1,hevc,vp8,vp9,av1,prores
hwdec-codecs=all

# 启用直接渲染(默认: yes)。
# 如果设置为 yes ,视频将被直接解码到GPU video memory(或暂存缓冲区)。
# 这可以加快视频上传速度,对高分辨率或慢速硬件可能有帮助。
vd-lavc-dr=yes

########
# 功能 #
########

# 让mpv在没有文件可以播放时空闲等待而不是退出。
idle=yes

# 以暂停状态启动播放器
# pause=yes     

# 循环一个文件N次,inf 表示永远,no 表示正常播放。
loop-file=no

# 循环一个播放列表N次,inf 表示永远,no 表示正常播放。
loop-playlist=no

# 允许视频解码器在跳转过程中丢帧,如果这些帧在跳转的目标之前。
hr-seek-framedrop=yes

# 在退出时总是保存当前的播放位置。
save-position-on-quit=yes

## 窗口相关

# 全屏播放。
fullscreen=no  

# 窗口边框和装饰。
border=no

# 将初始窗口尺寸设置为由 WxH 指定的最大尺寸,不改变窗口的长宽比。
autofit=70%

# 将窗口尺寸锁定为视频长宽。
keepaspect-window=yes

## 缓存相关

# 播放网络视频时的向后缓存大小(KiB或MiB)
# 该选项可以用来限制最大的预读数。
demuxer-max-bytes=50MiB   

########
# 字幕 #
########

# 加载与视频文件名匹配的额外字幕文件。参数指定了外部字幕文件的匹配模式。
# fuzzy 加载包含媒体文件名的所有字幕
sub-auto=fuzzy

########
# 截图 #
########

# 设置用于保存屏幕截图的图像文件类型。
screenshot-format=png

# 指定用于保存屏幕截图的文件名模板。
screenshot-template="%{filename:MPV_Screenshot}_%P"

# 存储屏幕截图在此目录中。
screenshot-directory= "~/Pictures/"

直播

直播源

播放方法

mpv --playlist-start=1 --playlist="https://raw.githubusercontent.com/zbefine/iptv/main/iptv.m3u"

稳定地址

IPTV提供商

  • IPTV Shop - 超过6000个直播电视频道+ 4000个影视节目(VOD)。
  • BestBuyIPTV 超过38个国家/地区的7300个高清频道和9600 VOD 1080p。
  • LyngSat Stream 公共链接到互联网上传输的3018个线性电视频道和2963个线性无线电频道。
  • FreetuxTV WebTV Manager - WebTV和Web Radio的免费数据库。
  • CXTv 来自世界各地的1308个电视频道和287个摄像机。
  • Necro IPTV 提供所有优质的英国,爱尔兰,德国,土耳其,阿拉伯语,美国和加拿大频道。

电视频道信息

  • LyngSat 卫星电视频道的数据库,其中包含捕获信号所必需的信息。
  • LyngSat Logo - 电视频道徽标的集合。
  • TV Address - 电视频道信息。

其他工具

  • WebGrab + Plus 多站点增量XMLTV EPG采集器。
  • IPTV Checker — Node.js的IPTV播放列表检查器
  • Streamtest 免费且易于使用的基于Web的流测试器实用程序。
EPG

当我们过去看有线电视时,我们会依靠电视指南来了解接下来要播放什么节目或电影,或者我们在特定时间可以期待什么。 现在我们生活在一个更现代的世界中,具有相同功能的指南也发生了变化。 如今,在观看直播电视时依赖电子节目指南或 EPG。

什么是IPTV?

对于不知道或不熟悉的人来说,互联网协议电视或 IPTV 本质上是一种即使没有电缆也可以通过互联网观看直播电视频道的方式。 大多数时候,IPTV 订阅比有线电视便宜得多,这就是为什么许多剪线钳决定选择这种方式的原因,尤其是当他们想削减开支时。 此外,您无需订阅有线电视即可安装和使用 IPTV,因此您可以毫无问题地在任何受支持的设备上下载 IPTV 应用程序。

有很多可用的 IPTV 服务,其中大多数提供数百或数千个频道可供浏览。 但是,无论您使用哪种 IPTV 服务,它通常都会附带一个 EPG,如果您正在寻找特定节目,您可以查看它。

EPG怎么样?

现在,让我们更多地讨论 EPG。 也称为电子服务指南 (ESG) 或交互式节目指南 (IPG),您可以参考 EPG 以查看电视节目以及完整的详细信息列表。 这些详细信息包括节目网络、类型、放映时间、描述、预览等。

话虽如此,EPG 的界面并不完全相同。 一些 EPG 只展示已经播放或正在播出的节目,而另一些则展示其他节目即将播出的时间表。

如何为IPTV设置EPG?

仅对于使用免费Internet访问中包含的M3U播放列表或自行创建它们的用户,才需要有关设置EPG的知识。对于只想通过网络收看电视频道而又不打算学习此主题的用户,可以按照自定义指南在Android或Windows上安装任何IPTV播放器。没有EPG的M3U文件如下所示:

#EXTM3U
#EXTINF:0,Europa Plus电视#EXTGRP:音乐http://23acbfe8.ucomist.net/iptv/5K6RMPTM6L8S2Y/115/index.m3u8
#EXTINF:0,MUZ-TV #EXTGRP:音乐http://23acbfe8.ucomist.net/iptv/5K6RMPTM6L8S2Y/116/index.m3u8
#EXTINF:0,BRIDGE TV俄语热播#EXTGRP:音乐http://23acbfe8.ucomist.net/iptv/5K6RMPTM6L8S2Y/120/index.m3u8
#EXTINF:0,Bridge TV #EXTGRP:音乐http://23acbfe8.ucomist.net/iptv/5K6RMPTM6L8S2Y/122/index.m3u8

将标记为#EXTM3U的第一行更改为:#EXTM3U url-tvg="http://iptvx.one/epg/epg_lite.xml.gz" 这样的形式。

EPG 列表

VLC

appimage version

VLC is a free and open source cross-platform multimedia player and framework that plays most multimedia files, and various streaming protocols.

Skins

  • Put the downloaded VLT files in the following folder: ~/.local/share/vlc/skins2
  • Then open your VLC settings and change your interface from native to skins ( Tools => Performances => Interface => Use custom skin => Skin resource file => Save ). You can choose your desired skin already there or change it when you are in the skins mode by rightclicking somewhere on the skin and going to Interface>Choose Skin.
  • VLC needs to be restarted to change to skins mode.

有些主题只支持英文。

管理流媒体

VLC 的 Android 版本 与 Linux 桌面版本操作是不同的:

  • 在 Android 上,选择 More,点击 New stream 添加添加流媒体,添加的流媒体会在Streams展示,可以将所有添加的流媒体分组到playlist,playlist可以备份成名为 vlc_media.db 的 sqlite db,详情看How to Backup and Restore Playlists

  • 在 Linux 桌面端,需在 Media => Open Network Stream… 打开流媒体进行播放,打开的流媒体会在 Playlist 中展示,但是关闭 VLC 后就会清空 Playlist。要保存 Playlist,需右键 => Save Playlist to File… 保存为 xspf 文件,之后点击该文件播放 Playist 就行。Playlist 例子如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <playlist xmlns="http://xspf.org/ns/0/" xmlns:vlc="http://www.videolan.org/vlc/playlist/ns/0/" version="1">
     <title>Playlist</title>
     <trackList>
      <track>
       <location>http://sk.cri.cn/915.m3u8</location>
       <title>輕鬆調頻</title>
       <duration>8950</duration>
       <extension application="http://www.videolan.org/vlc/playlist/0">
        <vlc:id>0</vlc:id>
        <vlc:option>network-caching=1000</vlc:option>
       </extension>
      </track>
      <track>
       <location>http://sk.cri.cn/887.m3u8</location>
       <title>劲曲调频</title>
       <duration>8950</duration>
       <extension application="http://www.videolan.org/vlc/playlist/0">
        <vlc:id>1</vlc:id>
        <vlc:option>network-caching=1000</vlc:option>
       </extension>
      </track>
     </trackList>
     <extension application="http://www.videolan.org/vlc/playlist/0">
      <vlc:item tid="0"/>
      <vlc:item tid="1"/>
     </extension>
    </playlist>
    

    手动编写的话<duration>可能是错的(不影响播放),可以在打开后 xspf 文件后再保存一次来覆盖该文件。

SMPlayer

多媒体播放器

Kodi

具有库支持的免费跨平台媒体播放器。

Shotcut

Shotcut is a free, open source, cross-platform video editor.

DaVinci Resolve

专业的剪辑、调色、特效和音频后期制作!

Download

Aria2

Aria2是一款开源下载工具,可帮助简化不同设备和服务器之间的下载过程。它支持磁力链接、BT种子、http等类型的文件下载,与迅雷相比,Aria2有着优秀的性能及较低的资源占用,架构本身非常轻巧,通常只需要4兆字节(HTTP下载)到9兆字节(用于BitTorrent交互)之间。最重要的一点是Aria2完全免费!

sudo apt-get install aria2

下载安装完成之后,可以通过输入 aria2c -v 来验证是否安装成功。

Usage

命令行使用

使用Aria2下载文件,只需在命令后附加地址即可:

aria2c URL

下载后以其他名称保存文件

aria2c -o fileName URL

下载多个文件

aria2c -Z URL URL

从列表下载文件:

aria2c -i URLs.txt

限制下载速度:

# 单个文件
aria2c –max-download-limit=500k URL
# 全局
aria2c –max-overall-download-limit=500k URL 

断点续传:

aria2c -c URL

下载磁力链接文件:要下载磁力链接文件,如果下载没有速度,可以添加--bt-tracker=选项,tracker 中用 , 隔开:

aria2c --bt-tracker=tracker,tracker torrent

tracker 服务器:

分段下载:可以加快文件的下载速度,对于下载大文件时特别有用,-s 后面的参数值介于1~5之间,你可以根据实际情况选择。下面命令将使用2连接来下载该文件:

aria2c -s 2 URL

后台下载:

aria2c -D url
aria2c –deamon=true url

验证文件:

aria2c –checksum=md5=提供的md5

设置dht端口:

aria2c –dht-listen-port=1234 torrent

下载需要引用页的文件:

aria2c –referer=referurl URL

下载需要Cookie验证的文件:

aria2c –essay-header=’Cookie:key=value’ URL
aria2c –load-cookies=cookie文件 URL

从密码保护的网站下载一个文件:

aria2c --http-user=xxx --http-password=xxx URL
aria2c --ftp-user=xxx --ftp-password=xxx URL

注意:当源地址存在诸如&,*等shell的特殊字符,请使用单引号或双引号把URI包含起来。

代理

/usr/bin/aria2c --conf-path=/path/of/aria2.conf --{http,https,ftp,all}-proxy="[http://][USER:PASSWORD@]HOST[:PORT]"

例如

/usr/bin/aria2c --conf-path=/home/kurome/.opt/aria2/aria2.conf --http-proxy="http://127.0.0.1:7890"

覆盖先前定义的代理, 使用 "",例如:

/usr/bin/aria2c --conf-path=/path/of/aria2.conf --all-proxy=""

RPC Server 模式

该模式可以配合 Web UI 进行图形管理。默认启动是 6800 端口,怕别人盗用,可以设置用户名和密码(1.18.4以上版本支持密钥)。

aria2c --enable-rpc --rpc-listen-all --rpc-allow-origin-all -c  --dir ~/Download

Configuration

默认情况下,aria2 检查旧路径 $HOME/.opt/aria2/aria2.conf 是否存在,否则它会将 $XDG_CONFIG_HOME/aria2/aria2.conf 解析为它的配置文件。 您可以使用 --conf-path 选项指定配置文件的路径。 如果您不想使用配置文件,请使用 --no-conf 选项。

配置详解

# Description: Awesome Aria2 configuration file
# Version: 2021.09.15

## '#'开头为注释内容, 选项都有相应的注释说明, 根据需要修改 ##
## 被注释的选项填写的是默认值, 如为空则无默认设置,请自行选取需要更改的添加到你的配置文件中 ##

## 文件保存设置 ##

# 下载路径(可使用绝对路径或相对路径), 默认: 当前启动位置
#dir=
dir=/home/kurome/Downloads

# 磁盘缓存
# 启用磁盘缓存. 如果设置为 0, 将禁用磁盘缓存. 此功能将下载的数据缓存在内存中, 最多占用此选项设置的字节数. 缓存存储由 aria2 实例创建并对所有下载共享. 由于数据以较大的单位写入并按文件的偏移重新排序, 所以磁盘缓存的一个优点是减少磁盘的 I/O. 如果调用哈希检查时并且数据缓存在内存中时, 将不需要从磁盘中读取. 大小可以包含 K 或 M (1K = 1024, 1M = 1024K).
disk-cache=64M

# 文件预分配方式, 可选:none, prealloc, trunc, falloc, 默认:prealloc
# 预分配对于机械硬盘可有效降低磁盘碎片、提升磁盘读写性能、延长磁盘寿命。
# 机械硬盘使用 ext4(具有扩展支持),btrfs,xfs 或 NTFS(仅 MinGW 编译版本)等文件系统建议设置为 falloc
# 若无法下载,提示 fallocate failed.cause:Operation not supported 则说明不支持,请设置为 none
# prealloc 分配速度慢, trunc 无实际作用,不推荐使用。
# 固态硬盘不需要预分配,只建议设置为 none ,否则可能会导致双倍文件大小的数据写入,从而影响寿命。
file-allocation=none

# 文件分配限制
# 不对比此参数设置大小小的分配文件. 您可以增加数值的单位 K 或 M (1K = 1024, 1M = 1024K).
no-file-allocation-limit=64M

# 断点续传
# 继续下载部分完成的文件. 启用此选项可以继续下载从浏览器或其他程序按顺序下载的文件. 此选项目前只支持 HTTP(S)/FTP 下载的文件.
continue=true

# 始终断点续传
# 始终断点续传. 如果设置为"是", aria2 始终尝试断点续传, 如果无法恢复, 则中止下载. 如果设置为"否", 对于不支持断点续传的 URI 或 aria2 遇到 N 个不支持断点续传的 URI (N 为 --max-resume-failure-tries 选项设置的值), aria2 会从头下载文件. 参见 --max-resume-failure-tries 参数.
always-resume=false

# 最大断点续传尝试次数
# 当 --always-resume 选项设置为"否"时, 如果 aria2 检测到有 N 个 URI 不支持断点续传时, 将从头开始下载文件. 如果 N 设置为 0, 当所有 URI 都不支持断点续传时才会从头下载文件. 参见 --always-resume 选项.
max-resume-failure-tries=0

# 获取服务器文件时间
# 从 HTTP/FTP 服务获取远程文件的时间戳, 如果可用将设置到本地文件
remote-time=true

## 进度保存设置 ##

# 从会话文件中读取下载任务
input-file=/home/kurome/.opt/aria2/aria2.session

# 会话文件保存路径
# 当退出时保存错误及未完成的任务到指定的文件中. 必须用绝对路径
# 您可以在重启 aria2 时使用 --input-file 选项重新加载. 如果您希望输出的内容使用 GZip 压缩, 您可以在文件名后增加 .gz 扩展名. 请注意, 通过 aria2.addTorrent() 和 aria2.addMetalink() RPC 方法添加的下载, 其元数据没有保存到文件的将不会保存. 通过 aria2.remove() 和 aria2.forceRemove() 删除的下载将不会保存.
#save-session=
save-session=/home/kurome/.opt/aria2/aria2.session

# 任务状态改变后保存会话的间隔时间(秒), 0 为仅在进程正常退出时保存, 默认:0
# 为了及时保存任务状态、防止任务丢失,此项值只建议设置为 1
save-session-interval=1

# 自动保存任务进度到控制文件(*.opt/aria2)的间隔时间(秒),0 为仅在进程正常退出时保存,默认:60
# 不论设置的值为多少, aria2 会在任务结束时保存控制文件. 可以设置的值为 0 到 600.
# 此项值也会间接影响从内存中把缓存的数据写入磁盘的频率
# 想降低磁盘 IOPS (每秒读写次数)则提高间隔时间
# 想在意外非正常退出时尽量保存更多的下载进度则降低间隔时间
# 非正常退出:进程崩溃、系统崩溃、SIGKILL 信号、设备断电等
auto-save-interval=20

# 强制保存,即使任务已完成也保存信息到会话文件, 默认:false
# 即使任务完成或删除时使用 --save-session 选项时也保存该任务. 此选项在这种情况下还会保存控制文件. 此选项可以保存被认为已经完成但正在做种的 BT 任务.
# 开启后会在任务完成后保留 .opt/aria2 文件,文件被移除且任务存在的情况下重启后会重新下载。
# 关闭后已完成的任务列表会在重启后清空。
force-save=false


## 下载连接设置 ##

# 文件未找到重试次数
# 如果 aria2 从远程 HTTP/FTP 服务器收到 "文件未找到" 的状态超过此选项设置的次数后下载将会失败. 设置为 0 将会禁用此选项. 此选项仅影响 HTTP/FTP 服务器. 重试时同时会记录重试次数, 所以也需要设置 --max-tries 这个选项.
max-file-not-found=10

# 最大尝试次数
# 设置最大尝试次数. 0 表示不限制,默认:5
max-tries=0

# 重试等待时间, 默认:0 (禁用)
# 设置重试间隔时间(秒). 当此选项的值大于 0 时, aria2 在 HTTP 服务器返回 503 响应时将会重试.
retry-wait=10

# 连接超时时间
# 设置建立 HTTP/FTP/代理服务器 连接的超时时间(秒). 当连接建立后, 此选项不再生效, 请使用 --timeout 选项.
connect-timeout=10

# 超时时间。默认:60
timeout=10

# 最大同时下载任务数, 运行时可修改, 默认:5
max-concurrent-downloads=5

# 单服务器最大连接线程数, 任务添加时可指定, 默认:1
# 最大值为 16 (增强版无限制), 且受限于单任务最大连接线程数(split)所设定的值。
max-connection-per-server=16

# 单任务最大连接线程数, 任务添加时可指定, 默认:5
# 下载时使用 N 个连接. 如果提供超过 N 个 URI 地址, 则使用前 N 个地址, 剩余的地址将作为备用. 如果提供的 URI 地址不足 N 个, 这些地址多次使用以保证同时建立 N 个连接. 同一服务器的连接数会被 --max-connection-per-server 选项限制.
split=64

# 文件最小分段大小, 添加时可指定, 默认:20M
# aria2 不会分割小于 2*SIZE 字节的文件. 例如, 文件大小为 20MB, 如果 SIZE 为 10M, aria2 会把文件分成 2 段 [0-10MB) 和 [10MB-20MB), 并且使用 2 个源进行下载 (如果 --split >= 2). 如果 SIZE 为 15M, 由于 2*15M > 20MB, 因此 aria2 不会分割文件并使用 1 个源进行下载. 您可以增加数值的单位 K 或 M (1K = 1024, 1M = 1024K). 可以设置的值为: 1M-1024M.
# 理论上值越小使用下载分段就越多,所能获得的实际线程数就越大,下载速度就越快,但受限于所下载文件服务器的策略。
min-split-size=4M

# 文件分片大小,最小值为 1M,默认:1M
# 设置 HTTP/FTP 下载的分配大小. aria2 根据这个边界分割文件. 所有的分割都是这个长度的倍数. 此选项不适用于 BitTorrent 下载. 如果 Metalink 文件中包含分片哈希的结果此选项也不适用.
piece-length=1M

# 允许分片大小变化。默认:false
# 如果设置为"否", 当分片长度与控制文件中的不同时, aria2 将会中止下载. 如果设置为"是", 您可以继续, 但部分下载进度将会丢失.
allow-piece-length-change=true

# 分片选择算法
# 指定 HTTP/FTP 下载使用的分片选择算法. 分片表示的是并行下载时固定长度的分隔段. 如果设置为"默认", aria2 将会按减少建立连接数选择分片. 由于建立连接操作的成本较高, 因此这是合理的默认行为. 如果设置为"顺序", aria2 将选择索引最小的分片. 索引为 0 时表示为文件的第一个分片. 这将有助于视频的边下边播. --enable-http-pipelining 选项有助于减少重连接的开销. 请注意, aria2 依赖于 --min-split-size 选项, 所以有必要对 --min-split-size 选项设置一个合理的值. 如果设置为"随机", aria2 将随机选择一个分片. 就像"顺序"一样, 依赖于 --min-split-size 选项. 如果设置为"几何", aria2 会先选择索引最小的分片, 然后会为之前选择的分片保留指数增长的空间. 这将减少建立连接的次数, 同时文件开始部分将会先行下载. 这也有助于视频的边下边播.
#stream-piece-selector=default

# 最小速度限制
# 当下载速度低于此选项设置的值(B/s) 时将会关闭连接. 0 表示不设置最小速度限制. 您可以增加数值的单位 K 或 M (1K = 1024, 1M = 1024K). 此选项不会影响 BT 下载.
lowest-speed-limit=0

# 全局最大下载速度
# 设置全局最大下载速度 (字节/秒). 0 表示不限制. 您可以增加数值的单位 K 或 M (1K = 1024, 1M = 1024K).
max-overall-download-limit=0

# 最大下载速度
# 设置每个任务的最大下载速度 (字节/秒). 0 表示不限制. 您可以增加数值的单位 K 或 M (1K = 1024, 1M = 1024K).
max-download-limit=0

# 禁用 IPv6, 默认:false
disable-ipv6=true

# 支持 GZip
# 如果远程服务器的响应头中包含 Content-Encoding: gzip 或 Content-Encoding: deflate , 将发送包含 Accept: deflate, gzip 的请求头并解压缩响应.
http-accept-gzip=true

# URI 复用
# 当所有给定的 URI 地址都已使用, 继续使用已经使用过的 URI 地址.
reuse-uri=false

# URI 选择算法
# 指定 URI 选择的算法. 可选的值包括 "按顺序", "反馈" 和 "自适应". 如果设置为"按顺序", URI 将按列表中出现的顺序使用. 如果设置为"反馈", aria2 将根据之前的下载速度选择 URI 列表中下载速度最快的服务器. 同时也将有效跳过无效镜像. 之前统计的下载速度将作为服务器状态文件的一部分, 参见 --server-stat-of 和 --server-stat-if 选项. 如果设置为"自适应", 将从最好的镜像和保留的连接里选择一项. 补充说明, 其返回的镜像没有被测试过, 同时如果每个镜像都已经被测试过时, 返回的镜像还会被重新测试. 否则, 其将不会选择其他镜像. 例如"反馈", 其使用服务器状态文件.
#uri-selector=feedback

# 禁用 netrc,默认:false
no-netrc=true

# .netrc 文件路径
#netrc-path=$(HOME)/.netrc

# 允许覆盖
# 如果相应的控制文件不存在时从头重新下载文件. 参见 --auto-file-renaming 选项.
allow-overwrite=false

# 文件自动重命名。默认:true
# 重新命名已经存在的文件. 此选项仅对 HTTP(S)/FTP 下载有效. 新的文件名后会在文件名后、扩展名 (如果有) 前追加句点和数字(1..9999).
auto-file-renaming=true

# 使用 UTF-8 处理 Content-Disposition,默认:false
# 处理 "Content-Disposition" 头中的字符串时使用 UTF-8 字符集来代替 ISO-8859-1, 例如, 文件名参数, 但不是扩展版本的文件名.
content-disposition-default-utf8=true

# 最低 TLS 版本,可选:TLSv1.1、TLSv1.2、TLSv1.3 默认:TLSv1.2
#min-tls-version=TLSv1.2


## BT/PT 下载设置 ##

# BT 监听端口(TCP), 默认:6881-6999
# 设置 BT 下载的 TCP 端口. 多个端口可以使用逗号 "," 分隔, 例如: 6881,6885. 您还可以使用短横线 "-" 表示范围: 6881-6999, 或可以一起使用: 6881-6889, 6999.
# 直通外网的设备,比如 VPS ,务必配置防火墙和安全组策略允许此端口入站
# 内网环境的设备,比如 NAS ,除了防火墙设置,还需在路由器设置外网端口转发到此端口
listen-port=51413

# DHT 网络与 UDP tracker 监听端口(UDP), 默认:6881-6999
# 设置 DHT (IPv4, IPv6) 和 UDP 服务器使用的 UCP 端口. 多个端口可以使用逗号 "," 分隔, 例如: 6881,6885. 您还可以使用短横线 "-" 表示范围: 6881-6999, 或可以一起使用: 6881-6889, 6999.
# 因协议不同,可以与 BT 监听端口使用相同的端口,方便配置防火墙和端口转发策略。
dht-listen-port=51413

# 启用 DHT (IPv4), 默认:true
# 启用 IPv4 DHT 功能. 此选项同时会启用 UDP 服务器支持. PT 下载(私有种子)会自动禁用
enable-dht=true

# 启用 DHT (IPv6),默认:false
# 启用 IPv6 DHT 功能. 如果种子设置为私有, 即使此选项设置为"是", aria2 也不会启用 DHT. 使用 --dht-listen-port 选项设置监听的端口.
# 在没有 IPv6 支持的环境开启可能会导致 DHT 功能异常
enable-dht6=false

# 外部 IP 地址
# 指定用在 BitTorrent 下载和 DHT 中的外部 IP 地址. 它可能被发送到 BitTorrent 服务器. 对于 DHT, 此选项将会报告本地节点正在下载特定的种子. 这对于在私有网络中使用 DHT 非常关键. 虽然这个方法叫外部, 但其可以接受各种类型的 IP 地址.
# 使用场景:在家庭宽带没有公网 IP 的情况下可以把 BT 和 DHT 监听端口转发至具有公网 IP 的服务器,在此填写服务器的 IP ,可以提升 BT 下载速率。
#bt-external-ip=

# DHT (IPv4) 文件,默认:$HOME/.opt/aria2/dht.dat
# 修改 IPv4 DHT 路由表文件路径.
dht-file-path=/home/kurome/.opt/aria2/dht.dat

# DHT (IPv6) 文件,默认:$HOME/.opt/aria2/dht6.dat
# 修改 IPv6 DHT 路由表文件路径.
dht-file-path6=/home/kurome/.opt/aria2/dht6.dat

# IPv4 DHT 网络引导节点
dht-entry-point=dht.transmissionbt.com:6881

# IPv6 DHT 网络引导节点
dht-entry-point6=dht.transmissionbt.com:6881

# 启用本地节点发现(LPD),PT 下载(私有种子)会自动禁用,默认:false
bt-enable-lpd=true

# 指定用于本地节点发现的接口,可能的值:接口,IP地址
# 如果未指定此选项,则选择默认接口。
#bt-lpd-interface=

# 启用节点交换, 默认:true
# 启用节点交换扩展. 如果种子设置为私有, 即使此选项设置为"是", aria2 也不会启用此功能.
enable-peer-exchange=true

# BT 下载最大连接数(单任务),运行时可修改。0 为不限制,默认:55
# 理想情况下连接数越多下载越快,但在实际情况是只有少部分连接到的做种者上传速度快,其余的上传慢或者不上传。
# 如果不限制,当下载非常热门的种子或任务数非常多时可能会因连接数过多导致进程崩溃或网络阻塞。
# 进程崩溃:如果设备 CPU 性能一般,连接数过多导致 CPU 占用过高,因资源不足 Aria2 进程会强制被终结。
# 网络阻塞:在内网环境下,即使下载没有占满带宽也会导致其它设备无法正常上网。因远古低性能路由器的转发性能瓶颈导致。
bt-max-peers=128

# BT 下载期望速度值(单任务),运行时可修改。单位 K 或 M 。默认:50K
# BT 下载速度低于此选项值时会临时提高连接数来获得更快的下载速度,不过前提是有更多的做种者可供连接。
# 实测临时提高连接数没有上限,但不会像不做限制一样无限增加,会根据算法进行合理的动态调节。
bt-request-peer-speed-limit=10M

# 全局最大上传速度, 运行时可修改, 默认:0 (无限制)
# 设置全局最大上传速度 (字节/秒). 0 表示不限制. 您可以增加数值的单位 K 或 M (1K = 1024, 1M = 1024K).
# 设置过低可能影响 BT 下载速度
max-overall-upload-limit=2M

# 单任务上传速度限制, 默认:0 (无限制)
# 设置每个任务的最大上传速度 (字节/秒). 0 表示不限制. 您可以增加数值的单位 K 或 M (1K = 1024, 1M = 1024K).
max-upload-limit=0

# 最小分享率, 0 为一直做种, 默认:1.0
# 指定分享率. 当分享率达到此选项设置的值时会完成做种. 强烈建议您将此选项设置为大于等于 1.0. 如果您想不限制分享比率, 可以设置为 0.0. 如果同时设置了 --seed-time 选项, 当任意一个条件满足时将停止做种.
seed-ratio=1.0

# 最小做种时间(分钟)
# 此选项设置为 0 时, 将在 BT 任务下载完成后不进行做种.
seed-time=30

# 做种前检查文件哈希, 默认:true
# 如果设置为"是", 当使用 --check-integrity 选项完成哈希检查及文件完成后才继续做种. 如果您希望仅当文件损坏或未完成时检查文件, 请设置为"否". 此选项仅对 BT 下载有效
bt-hash-check-seed=true

# 继续之前的BT任务时, 无需再次校验, 默认:false
# 不检查之前下载文件中每个分片的哈希值.
bt-seed-unverified=false

# BT tracker 服务器连接超时时间(秒)。默认:60
# 建立连接后,此选项无效,将使用 bt-tracker-timeout 选项的值
bt-tracker-connect-timeout=10

# BT tracker 服务器超时时间(秒)。默认:60
bt-tracker-timeout=10

# BT 服务器连接间隔时间。默认:0 (自动)
# 设置请求 BT 服务器的间隔时间 (秒). 此选项将完全覆盖服务器返回的最小间隔时间和间隔时间, aria2 仅使用此选项的值.如果设置为 0, aria2 将根据服务器的响应情况和下载进程决定时间间隔.
#bt-tracker-interval=0

# BT 下载优先下载文件开头或结尾
# 尝试先下载每个文件开头或结尾的分片. 此选项有助于预览文件. 参数可以包括两个关键词: head 和 tail. 如果包含两个关键词, 需要使用逗号分隔. 每个关键词可以包含一个参数, SIZE. 例如, 如果指定 head=SIZE, 每个文件的最前 SIZE 数据将会获得更高的优先级. tail=SIZE 表示每个文件的最后 SIZE 数据. SIZE 可以包含 K 或 M (1K = 1024, 1M = 1024K).
bt-prioritize-piece=head=32M,tail=32M

# 保存通过 WebUI(RPC) 上传的种子文件(.torrent),默认:true
# 在 dir 选项设置的目录中保存上传的种子文件或 Metalink 文件. 文件名包括 SHA-1 哈希后的元数据和扩展名两部分. 对于种子文件, 扩展名为 '.torrent'. 对于 Metalink 为 '.meta4'. 如果此选项设置为"否", 通过 aria2.addTorrent() 或 aria2.addMetalink() 方法添加的下载将无法通过 --save-session 选项保存.
# 所有涉及种子文件保存的选项都建议开启,不保存种子文件有任务丢失的风险。
# 通过 RPC 自定义临时下载目录可能不会保存种子文件。
rpc-save-upload-metadata=true

# 下载种子文件(.torrent)自动开始下载, 默认:true,可选:false|mem
# true:保存种子文件
# false:仅下载种子文件
# mem:将种子保存在内存中
# 如果设置为"是"或"仅内存", 当后缀为 .torrent 或内容类型为 application/x-bittorrent 的文件下载完成时, aria2 将按种子文件读取并下载该文件中提到的文件. 如果设置为"仅内存", 该种子文件将不会写入到磁盘中, 而仅会存储在内存中. 如果设置为"否", 则 .torrent 文件会下载到磁盘中, 但不会按种子文件读取并且其中的文件不会进行下载.
follow-torrent=true

# 种子文件下载完后暂停任务,默认:false
# 在开启 follow-torrent 选项后下载种子文件或磁力会自动开始下载任务进行下载,而同时开启当此选项后会建立相关任务并暂停。
pause-metadata=false

# 保存磁力链接元数据为种子文件(.torrent), 默认:false
# 保存种子文件为 ".torrent" 文件. 此选项仅对磁链生效. 文件名为十六进制编码后的哈希值及 ".torrent"后缀. 保存的目录与下载文件的目录相同. 如果相同的文件已存在, 种子文件将不会保存.
bt-save-metadata=true

# 加载已保存的元数据文件(.torrent),默认:false
# 当使用磁链下载时, 在从 DHT 获取种子元数据之前, 首先尝试加载使用 --bt-save-metadata 选项保存的文件. 如果文件加载成功, 则不会从 DHT 下载元数据.
bt-load-saved-metadata=true

# 删除 BT 下载任务中未选择文件,默认:false
# 当 BT 任务完成后删除未选择的文件. 要选择需要下载的文件, 请使用 --select-file 选项. 如果没有选择, 则所有文件都默认为需要下载. 此选项会从磁盘上直接删除文件, 请谨慎使用此选项.
bt-remove-unselected-file=true

# BT强制加密, 默认: false
# 启用后将拒绝旧的 BT 握手协议并仅使用混淆握手及加密。可以解决部分运营商对 BT 下载的封锁,且有一定的防版权投诉与迅雷吸血效果。
# 此选项相当于后面两个选项(bt-require-crypto=true, bt-min-crypto-level=arc4)的快捷开启方式,但不会修改这两个选项的值。
bt-force-encryption=true

# BT加密需求,默认:false
# 启用后拒绝与旧的 BitTorrent 握手协议(\19BitTorrent protocol)建立连接,始终使用混淆处理握手。
#bt-require-crypto=true

# BT最低加密等级,可选:plain(明文),arc4(加密),默认:plain
# 设置加密方法的最小级别. 如果节点提供多种加密方法, aria2 将选择满足给定级别的最低级别.
#bt-min-crypto-level=arc4

# 分离仅做种任务,默认:false
# 从正在下载的任务中排除已经下载完成且正在做种的任务,并开始等待列表中的下一个任务。
# 统计当前活动下载任务(参见 -j 选项) 时排除仅做种的任务. 这意味着, 如果参数设置为 -j3, 此选项打开并且当前有 3 个正在活动的任务, 并且其中有 1 个进入做种模式, 那么其会从正在下载的数量中排除(即数量会变为 2), 在队列中等待的下一个任务将会开始执行. 但要知道, 在 RPC 方法中, 做种的任务仍然被认为是活动的下载任务.
bt-detach-seed-only=true

## 客户端伪装 ##

# 自定义 User Agent
user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Edg/93.0.961.47

# BT 客户端伪装
# PT 下载需要保持 user-agent 和 peer-agent 两个参数一致
# 部分 PT 站对 Aria2 有特殊封禁机制,客户端伪装不一定有效,且有封禁账号的风险。
# 自定义 User Agent,默认:aria2/$VERSION
#user-agent=Deluge 1.3.15
# Peer Agent
# 指定 BT 扩展握手期间用于节点客户端版本的字符串.
peer-agent=Deluge 1.3.15
# 节点 ID 前缀
# 指定节点 ID 的前缀. BT 中节点 ID 长度为 20 字节. 如果超过 20 字节, 将仅使用前 20 字节. 如果少于 20 字节, 将在其后不足随机的数据保证为 20 字节.
peer-id-prefix=-DE13F0-

## 执行额外命令 ##

# 下载停止后执行的命令
# 从 正在下载 到 删除、错误、完成 时触发。暂停被标记为未开始下载,故与此项无关。
#on-download-stop=/home/kurome/.opt/aria2/delete.sh

# 下载完成后执行的命令
# 此项未定义则执行 下载停止后执行的命令 (on-download-stop)
#on-download-complete=/home/kurome/.opt/aria2/clean.sh

# 下载错误后执行的命令
# 此项未定义则执行 下载停止后执行的命令 (on-download-stop)
#on-download-error=

# 下载暂停后执行的命令
#on-download-pause=

# 下载开始后执行的命令
#on-download-start=

# BT 下载完成后执行的命令
#on-bt-download-complete=


## RPC 设置 ##

# 启用 JSON-RPC/XML-RPC 服务器, 默认:false
enable-rpc=true

# 接受所有远程请求, 默认:false
# 在 RPC 响应头增加 Access-Control-Allow-Origin 字段, 值为 * .web界面跨域权限需要
rpc-allow-origin-all=true

# 允许外部访问, 默认:false
rpc-listen-all=true

# RPC 监听端口, 默认:6800
rpc-listen-port=6800

# RPC 密钥, v1.18.4新增功能, 取代 --rpc-user 和 --rpc-passwd 选项
rpc-secret=SetForYourself

# RPC 最大请求大小
# 设置 JSON-RPC/XML-RPC 最大的请求大小. 如果 aria2 检测到请求超过设定的字节数, 会直接取消连接.
rpc-max-request-size=10M

# RPC 服务 SSL/TLS 加密, 默认:false
# RPC 将通过 SSL/TLS 加密传输. RPC 客户端需要使用 https 协议连接服务器. 对于 WebSocket 客户端, 使用 wss 协议. 使用 --rpc-certificate 和 --rpc-private-key 选项设置服务器的证书和私钥.
# 不推荐开启,建议使用 web server 反向代理,比如 Nginx、Caddy ,灵活性更强。
#rpc-secure=

# 在 RPC 服务中启用 SSL/TLS 加密时的证书文件,
# 使用 PEM 格式时,您必须通过 --rpc-private-key 指定私钥
#rpc-certificate=/path/to/certificate.pem

# 在 RPC 服务中启用 SSL/TLS 加密时的私钥文件
#rpc-private-key=/path/to/certificate.key

# 事件轮询方式, 可选:epoll, kqueue, port, poll, select, 不同系统默认值不同
# 设置事件轮训的方法. 对于 epoll, kqueue, port 和 poll, 只有系统支持时才可用. 最新的 Linux 支持 epoll. 各种 *BSD 系统包括 Mac OS X 支持 kqueue. Open Solaris 支持 port. 默认值根据您使用的操作系统不同而不同.
#event-poll=select

## 高级选项 ##

# 启用异步 DNS 功能。默认:true
#async-dns=true

# 指定异步 DNS 服务器列表,未指定则从 /etc/resolv.conf 中读取。
#async-dns-server=119.29.29.29,223.5.5.5,8.8.8.8,1.1.1.1

# 指定单个网络接口,可能的值:接口,IP地址,主机名
# 如果接口具有多个 IP 地址,则建议指定 IP 地址。
# 已知指定网络接口会影响依赖本地 RPC 的连接的功能场景,即通过 localhost 和 127.0.0.1 无法与 Aria2 服务端进行讯通。
#interface=

# 指定多个网络接口,多个值之间使用逗号(,)分隔。
# 使用 interface 选项时会忽略此项。
#multiple-interface=

## 日志设置 ##

# 日志文件保存路径,默认:不保存
# 如果设置为 "-", 日志则写入到 stdout. 如果忽略或设置为空字符串(""), 日志将不会记录到磁盘上.
#log=

# 日志级别,可选 debug, info, notice, warn, error 。默认:debug
#log-level=warn

# 控制台日志级别,可选 debug, info, notice, warn, error ,默认:notice
console-log-level=notice

# 安静模式,禁止在控制台输出日志,默认:false
quiet=false

# 下载进度摘要输出间隔时间(秒),0 为禁止输出。默认:60
summary-interval=0

## BitTorrent trackers ##

# BT 服务器地址 2022/02/26
# 逗号分隔的 BT 服务器地址. 如果服务器地址在 --bt-exclude-tracker 选项中, 其将不会生效.
bt-tracker=udp://open.tracker.cl:1337/announce,udp://tracker.opentrackr.org:1337/announce,udp://9.rarbg.com:2810/announce,udp://www.torrent.eu.org:451/announce,udp://tracker2.dler.org:80/announce,udp://tracker.torrent.eu.org:451/announce,udp://tracker.moeking.me:6969/announce,udp://tracker.bitsearch.to:1337/announce,udp://tracker.0x.tf:6969/announce,udp://tracker-udp.gbitt.info:80/announce,udp://tr.cili001.com:8070/announce,udp://retracker.lanta-net.ru:2710/announce,udp://open.stealth.si:80/announce,udp://ipv4.tracker.harry.lu:80/announce,udp://explodie.org:6969/announce,udp://exodus.desync.com:6969/announce,udp://bt2.archive.org:6969/announce,udp://bt1.archive.org:6969/announce,https://tracker.nanoha.org:443/announce,https://tracker.lilithraws.org:443/announce

更多:Aria2 完美配置

Aria2 Web 控制台

Aira2 没有软件界面,程序员可以用代码执行任务,但普通用户怎样添加下载任务呢?——打开浏览器,输入网址aria2c.comYAAW 的中文版)就可以打开 Aria2 Web 控制台。

JSON-RPC Path 默认为: http://localhost:6800/jsonrpc,如果提示 “Aria2 RPC 服务器错误”,按照以下方法修改:

  • 普通情况设置为: http://host:port/jsonrpc
    • host: 指运行 Aria2 所在机器的 IP 或者名字
    • port: 使用 --rpc-listen-port 选项设置的端口, 未设置则是 6800;可通过 lsof -i:6800 查看端口是否被占用
  • 使用 --rpc-secret=xxxxxx 选项设置为: http://token:xxxxxx@host:port/jsonrpc
  • 使用 --rpc-user=user --rpc-passwd=pwd选项设置为: http://user:pwd@host:port/jsonrpc
  • 以上JSON-RPC Path 中的 http 可以用 ws 替代, 代表使用 WebSocket 协议。换用 ws 也可能解决 “Aria2 RPC 服务器错误”。
  • 当使用 https://aria2c.com 访问时, 可能需要使用 httpswss 协议。

在 Web UI 中对 Aria2 的设置会在 Aria2 重启后丢失,,必要的设置请写入配置文件。

已经下载完成的任务会在 Aria2 重启后消失, 除非启用了 --force-save 选项。

自启动

两个方案:

  1. 建立 desktop 文件放入 ~/.config/autostart 中:

    $ vim ~/.config/autostart/aria2.desktop
    [Desktop Entry]
    Type=Application
    Exec=/usr/bin/aria2c --conf-path=/home/kurome/.opt/aria2/aria2.conf -D --all-proxy=""
    Hidden=false
    NoDisplay=false
    X-GNOME-Autostart-enabled=true
    Name[en_US]=Aria2 Daemon
    Name=Aria2 Daemon
    Comment[en_US]=
    Comment=
    

    但这个就看桌面环境怎么操作了,比如我在 openSUSE KDE上的问题:开机登陆后,aria2 启动,但是 logout 后,aria2 就不启动了。

  2. 建议换 systemd,手写个 service

    $ sudo vim /usr/lib/systemd/system/aria2.service 
    [Unit]
    Description=Aria2c download manager
    After=network.target
    
    [Service]
    Type=simple
    User=kurome
    ExecStart=/usr/bin/aria2c --conf-path=/home/kurome/.opt/aria2/aria2.conf --all-proxy=""
    
    [Install]
    WantedBy=multi-user.target
    $ sudo systemctl enable --now aria2.service
    

    “systemd: Failed at step USER spawning /usr/sbin/opendkim: No such process”:注意 User 部分,首先必须按照如下写,其次必须是存在的用户

    User=tadeusz
    

Others

AriaNg

AriaNg 是一个让 aria2 更容易使用的现代 Web 前端

  • 使用很简单,将文件下载解压即可,可以本地打开 index.html 文件,也可上传到服务器。
  • 如果您懒得部署 AriaNg ,可以直接访问现成的 http://a2.ssss.fun
  • 打开后需要配置 AriaNg,打开 AriaNg 设置 - RPC,修改 Aria2 RPC 地址Aria2 RPC 密钥 ,点击 重新加载 AriaNg 即可。

WebUI-Aria2

这个项目的目标是创建世界上最好和最热门的界面来与 aria2 交互。

使用非常简单,只需在任何网络浏览器中下载并打开 index.html。

Aria2 for ….

比如 YAAW for ChromeAria2 for Chrome 、Aria2 for Edge 之类的。

在浏览器中直接内置一个 AriaNg,用于直接管理 Aria2。

Using Aria2 as a Daemon

运行 gnome-session-properties打开应用程序首选项管理(即 Ubuntu 中的 Startup Applications),添加:

  • Name: Aria2 Daemon
  • Command: /usr/bin/aria2c --conf-path=/home/kurome/.opt/aria2/aria2.conf -D

会建立 .config/autostart/aria2c.desktop

[Desktop Entry]
Type=Application
Exec=/usr/bin/aria2c --conf-path=/home/vane/.opt/aria2/aria2.conf -D
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name[en_US]=Aria2 Daemon
Name=Aria2 Daemon
Comment[en_US]=
Comment=

是这样滴,和很多BT客户端一样,Aria2有个dht.dat文件(开启ipv6还有个dht6.dat),这玩意用于存储一种叫做DHT Routing Table的东西,DHT网络由无数节点组成,你接触到一个后能通过它接触到更多的节点,Aria2我记得是有内置的节点,但是!如果你在Aria2第一次运行的时候直接下载磁力链接或者冷门种子,你很可能遇到连MetaData都无法获取的情况,这就是因为第一次只是初始化dht.dat文件,你本地不存在DHT Routing Table的缓存,所以你无法从DHT网络中获取足够的数据。

那么怎么办?我的建议是,找个热门种子(千万建议是种子,而不是磁力链接),然后下一波,挂着做种,过几个小时后退出Aria2,或者等Aria2会话自动保存,你会发现dht.dat从空文件变成有数据了,这时候你下载就会正常很多。

什么是 PT

答:PT(Private Tracker)下载其实也是Bt下载的一种,但有两个明显的改进:一是私密的小范围下载,二是进行流量统计,根据上载量决定你的权限。

BT下载时,软件会分析.torrent种子文件得到Tracker地址,然后连接Tracker服务器,服务器返回其他下载者的IP,下载者再与这些IP联系进行下载,从而减轻了服务器的负担,BT下载的Tracker是公开的,而Private Tracker 下载(PT下载)的Tracker则是私有的,每个人的Tracker是不同的,即passkey不同,passkey对PT下载者很重要,所以不要轻易泄露出去。

其实和通常BT相比,PT就是多了一个passkey验证,这样就能保证未注册的用户不能下载。所以passkey很重要,一旦发现有问题,就要到站点上去重置passkey。Tracker Server根据passkey把BT客户端上传量和下载量进行计算,从而算出分享率(上传量/下载量)。如果分享率太小,将会被删除帐号,从而不能下载。

这样Private Tracker 下载(PT下载)是一种小范围的BT下载,通过禁用DHT有要求地选择并控制用户数量,这样,在有限的范围内,下载的用户基本上都可以达到自己的宽带上限,Private Tracker 下载(PT下载)下载还通过论坛等方式的约束机制将BT下载的理念现实化,真正让用户做到下载的过程中努力上传。因此,Private Tracker 下载(PT下载)的速度很快,能够让用户款待得到最大程度的使用。

PT通过对做种时间和流量的要求在一定程度上避免了BT中存在的下完不做种的现象,因此在网络上,尤其是需要大文件(如高清)资源交换的时候广受欢迎,在PT站里,“水管”代表上传带宽的大小,大水管可以通过快速的上传获得积分,PT站点也会采取措施(比如做种时间,优惠等)使上传较慢的小水管能够参与贡献和共享资源。

RPC

首先了解什么叫RPC,为什么要RPC,RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。

比如说,一个方法可能是这样定义的:

Employee getEmployeeByName(String fullName)

那么:

  • 首先,要解决通讯的问题,主要是通过在客户端和服务器之间建立TCP连接,远程过程调用的所有交换的数据都在这个连接里传输。连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远程过程调用共享同一个连接。
  • 第二,要解决寻址的问题,也就是说,A服务器上的应用怎么告诉底层的RPC框架,如何连接到B服务器(如主机或IP地址)以及特定的端口,方法的名称名称是什么,这样才能完成调用。比如基于Web服务协议栈的RPC,就要提供一个endpoint URI,或者是从UDDI服务上查找。如果是RMI调用的话,还需要一个RMI Registry来注册服务的地址。
  • 第三,当A服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如TCP传递到B服务器,由于网络协议是基于二进制的,内存中的参数的值要序列化成二进制的形式,也就是序列化(Serialize)或编组(marshal),通过寻址和传输将序列化的二进制发送给B服务器。
  • 第四,B服务器收到请求后,需要对参数进行反序列化(序列化的逆操作),恢复为内存中的表达方式,然后找到对应的方法(寻址的一部分)进行本地调用,然后得到返回值。
  • 第五,返回值还要发送回服务器A上的应用,也要经过序列化的方式发送,服务器A接到后,再反序列化,恢复为内存中的表达方式,交给A服务器上的应用

img

为什么RPC呢?就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如比如不同的系统间的通讯,甚至不同的组织间的通讯。由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用,

RPC的协议有很多,比如最早的CORBA,Java RMI,Web Service的RPC风格,Hessian,Thrift,甚至Rest API。

其他 BT 下载工具
有支持ed2k的计划吗?

真是笑死我了,你们难道真的认为那所谓迅雷等国产BT下载软件会使用真正的eDonkey网络

非也!它们只不过通过ed2k链接所列出的哈希值 直接链接到它们服务器自身(如迅雷、百度)所存储的文件 或链接到BitTorrent协议的种子和磁力链接上。你们用的软件不是P2P(Peer to Peer),而是P2SP(Peer to Server and to Peer)!

如果你们用过真正的ed2k下载器(如eMuleaMule)的话,你们会发现,真正的eDonkey网络早已消亡,截至目前全球用户也就50-60万的样子。

最后,作为曾经的eMule老用户,我可以说明真正的eDonkey网络不仅有繁琐的排队机制,还有文件优先级网络优先级等复杂的设定,远比你们想像中难用的多。


warez groups

  • RELOADED

    RELOADED成立于2004年,前身是传奇破解组DEVIANCE,曾经在2次重大的政府扫荡中生存下来,由于竞争对手HOODLUM和VENGEANCE被端掉,RELOADED从此称霸PC游戏破解圈,在新游的首发破解上,RELOADED能占据80%。

    RELOADED也是国内最常见的PC游戏破解组,你在各个资源站看到标题写着某某游戏“R组”破解,就是他们的“杰作”。

    高光时刻:

    1、各大破解组都在追求游戏发售前破解游戏,而RELOADED最著名的应该就是2008年对《刺客信条》的破解了,R组在游戏发售1个月之前就放出破解版。

    2、修复了《彩虹六号:维加斯2》数字版的BUG,育碧当年对《彩虹六号:维加斯2》数字版无法运行的BUG毫无办法,最终只能给玩家发放RELOADED的游戏破解补丁…这次事件让育碧颜面扫地,却成就了RELOADED。

    3、打破《分裂细胞:混沌理论》424天不被破解的记录。

  • SKIDROW

    SKIDROW 是来自美国的游戏破解组,成立时间大概是上个世纪90年代,主要作品有《猎杀潜艇5》、《刺客信条2》等,之后由于人员解散,直到2007年 SKIDROW 才重新开始活跃。

    SKIDROW 在同行中的口碑一般,被RELOADED等破解组爆出过盗用其他破解组代码的料。

    1、 Skidrow成名于DRM事件,DRM是育碧的反破解系统,Skidrow破解组成功破解了育碧两袋DRM系统,最著名的作品是对《刺客信条2》的破解。

    2、2017年,继CPY之后,成功破解了最新的Denuvo64加密技术。并批评CPY只会用Emulation(仿真器)而不是真正的破解。

  • Razor1911

    Razor1911 是来自挪威的破解组,成立于1985年,最初由3个年轻的计算机爱好者组成,主要是破解Commodore64和amiga机种的游戏软件,名称中的1911是因为1991在16进制里写作777,代表不朽。

    作为老牌破解组之一, Razor1911在2001年和2004年的FBI两次反盗版行动中幸存下来,不知道是不是因为名字带来的好运。在业内,如果说RELOADED是以高产著称,那么Razor1911就是以技术见长。

    Razor1911破解组最著名的作品应该是《星际争霸:母巢之战》的硬盘版,间接导致了星际争霸在全世界的流行。

    1、制作《星际争霸:母巢之战》硬盘版,在这一版的星际争霸中,所有文件的体积加起来只有100m多一点,而最为经典的地方就在于他们把光盘版中两个600m左右的install.exe文件压缩到了只有22m的大小。

    2、破解《GTA4》和该游戏价值20万美元的SecuRom反破解系统。

    3、破解EA origin平台的加密技术。

    4、破解《孤岛危机》和《上古卷轴5:天际》。

  • CPY

    CPY全名 CONSPiR4CY,是来自于意大利的破解组,成立于1999年,相比上面的三大破解组成立较晚。但是最近几年,CPY在破解了Denuvo加密技术(D加密)后名声大噪,俨然已超越了上面三大破解组。

    在国内有CPY掌握核心技术的说法,Steam、EA origin、Denuvo等加密技术先后被CPY破解。

    高光时刻:

    1、2015年,继Steam平台后,EA origin平台加密技术被破解,宣布了这套加密系统彻底完蛋。

    2、破解D加密技术,随后一系列热门游戏遭到破解,包括:《合金装备5 幻痛》《古墓丽影 崛起》《毁灭战士4》《看门狗2》等等。

  • CODEX

    会破解D加密,如今几乎已经垄断破解业。并在.nfo文件招聘栏中提到CODEX什么都不要,只要竞争!

    2022年2月,CODEX宣告退休。

    • PLAZA
    • EMPRESS
  • STEAMPUNKS

youtube-dl

youtube-dl 是一个命令行程序,用于从 YouTube.com 和更多其他网站下载视频。 基于 Python 实现,不限于特定平台。

# 安装
$ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple youtube-dl
# 使用
$ youtube-dl [OPTIONS] URL [URL...]

当前版本(2021.06.06)不能下载哔哩哔哩播放列表,可以用类似软件如 you-getannie 代替。

Usage

下载视频或整个视频播放列表

  • 要从 Youtube 下载视频或整个视频播放列表,只需直接使用 URL 即可:youtube-dl [url]。程序自动选择一个最清晰的格式下载。
  • 如果要指定视频下载之后的名称,可以使用如下方式:youtube-dl -o '名称' [url]
  • 还可以在下载视频时附加更多详细信息,可用的参数有标题、上传者名称(频道名称)和视频上传日期等:youtube-dl -o '%(title)s by %(uploader)s on %(upload_date)s in %(playlist)s.%(ext)s' [ul]

查看视频的所有类型,只看不下载

命令:youtube-dl -F [url]或者youtube-dl --list-formats [url]。 这是一个列清单参数,执行后并不会下载视频,但能知道这个目标视频都有哪些格式存在,以便有选择的下载。

下载指定质量的视频和音频并自动合并

下载最佳/最差质量的音/视频文件:

默认情况下,youtube-dl将自主选择最佳质量的视频下载。 但是,也可以以特定的质量或格式来下载视频或播放列表

Youtube-dl 支持以下品质:

  • best选择最佳质量的音/视频文件
  • worst选择质量最差的格式(视频和音频)
  • bestvideo选择最佳质量的仅视频格式(例如DASH视频),可能无法使用。
  • worstvideo选择质量最差的纯视频格式,可能无法使用。
  • bestaudio选择最优质的音频格式,可能无法使用。
  • worstaudio选择质量最差的音频格式,可能无法使用。

例如,如果要自动选择并下载最佳质量格式(音频和视频),只需使用以下命令:youtube-dl -f best [url]

您还可以组合使用以下不同的格式选项:youtube-dl -f bestvideo+bestaudio [ul]。该命令将分别下载最高质量的仅视频和最高质量的纯音频格式,再用ffmpeg或avconv合并成一个最佳质量的mkv文件;如果您不想合并,请将+(加号)替换为,(逗号)即可分别得到最高质量的音频和视频(两个文件):youtube-dl -f 'bestvideo,bestaudio' [url]

下载指定质量的音/视频文件

-F 获取的所有视频格式的清单,最左边一列就是编号对应着不同的格式。由于YouTube的1080p及以上的分辨率都是音视频分离的,所以我们需要分别下载视频和音频,可以使用137+140这样的组合。如果系统中安装了ffmpeg的话,youtube-dl 会自动合并下好的视频和音频,然后自动删除单独的音视频文件:youtube-dl -f [format code] [url]

从播放列表下载视频时,某些视频可能没有相同的格式。 在这种情况下,可以按首选顺序指定多个格式代码,例如:命令youtube-dl -f 22/17/18 <playlist_url>将以格式 22 下载视频(如果可用);如果格式 22不可用,则它将下载格式 17(如果可用);如果格式 22 和 17 都不可用,最后尝试下载格式 18。如果所有格式代码都不匹配,Youtube-dl 会报出提示。还需要注意的是,斜杠是左关联的,即最左侧的格式代码是首选。

下载字幕

  • youtube-dl --write-sub [url]这样会下载一个vtt格式的英文字幕和mkv格式的1080p视频下来
  • youtube-dl --write-sub --skip-download [url]下载单独的vtt字幕文件,而不会下载视频
  • youtube-dl --write-sub --all-subs [url]下载所有语言的字幕(如果有的话)
  • youtube-dl --write-auto-sub [url]下载自动生成的字幕(YouTube only)

下载多个视频

  • youtube-dl <url1> <url2>有时我们需要一次下载多个不同的视频,此时我们只需用空格将多个URL分隔开即可。
  • youtube-dl -a url.txt也可以将要下载视频的URL全部放在文本文件中,并将其作为参数传递给youtube-dl。此命令将下载url.txt文件中所有URL指向的视频。

只下载(视频中的)音频

  • youtube-dl -x [url]仅从视频网站下载其音频。
  • youtube-dl -x --audio-format mp3 [ul]默认情况下,youtube-dl 将以Ogg (opus)格式保存音频。此命令将从给定的视频/播放列表下载音频,将其转换为 MP3 并将其保存在当前目录中。应注意:您应该安装 ffmpeg 或 avconv 将文件转换为 mp3 格式。

下载带有描述、元数据、注释、字幕和缩略图的视频

要下载视频及其他详细信息,如:说明、元数据、注释、字幕和缩略图等,请使用以下命令: youtube-dl --write-description --write-info-json --write-annotations --write-sub --write-thumbnail [url]

通过文件扩展名下载音/视频

  • 以您的首选格式下载视频,例如 MP4,只需执行:youtube-dl --format mp4 [url]或者youtube-dl -f mp4 [url]

  • 某些视频可能无法以您的首选格式提供。 在这种情况下,youtube-dl 将下载其他最佳可用格式。例如: youtube-dl -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' [ul] 此命令将下载最佳质量的MP4格式文件。如果 MP4 格式不可用,则它将下载其他最佳可用格式。

    限制下载视频的大小

从YouTube播放列表下载多个视频时,您可能只想下载特定大小的视频。例如:

  • 此命令不会下载任何小于指定大小(例如100MB)的视频:youtube-dl --min-filesize 100M <playlist_url>
  • 如果您不想下载大于给定大小的视频,可以这样:youtube-dl --max-filesize 100M <playlist_url>

我们还可以用组合格式,选择运算符来下载特定大小的视频。例如:

  • 以下命令将下载最佳视频格式但不大于 100MB 的视频:youtube-dl -f 'best[filesize<100M]' [url]

按日期下载视频

Youtube-dl 允许我们按照上传日期来筛选和下载视频或播放列表,例如:

  • 要下载 2019 年 8 月 1 日上传的视频,可以使用:youtube-dl --date 20190801 [URL]
  • 下载在特定日期或之前上传的视频:youtube-dl --datebefore 20190801 [URL]
  • 下载在特定日期或之后上传的视频:youtube-dl --dateafter 20190101 [URL]
  • 仅下载过去 6 个月内上传的视频:youtube-dl --dateafter now-6months [URL]
  • 下载特定时间段内(例如 2018 年 1 月 1 日至 2019 年 1 月 1 日)上传的视频:youtube-dl --dateafter 20180101 --datebefore 20190101 [URL]

从播放列表下载特定的视频

从播放列表下载特定的视频,是youtube-dl 的另一个非常有用的功能。例如:

  • 要从播放列表下载第 10 个文件,可使用:youtube-dl --playlist-items 10 [playlist_url]
  • 要下载多个指定的文件,只需用逗号分隔:youtube-dl --playlist-items 2,3,7,10 [playlist_url]

也可以按序号来指定要下载范围,例如:

  • 从第 10 个开始,直接下载完整个列表:youtube-dl --playlist-start 10 [playlist_url]
  • 在播放列表中仅下载从第 2 到第 5 的文件:youtube-dl --playlist-start 2 --playlist-end 5 [playlist_url]

Configuration

在 Linux 和 macOS 上,系统配置文件位于 /etc/youtube-dl.conf,用户配置文件位于 ~/.config/youtube-dl/config

# Continue on download errors, for example to skip unavailable videos in a playlist
--ignore-errors

# Time to wait before giving up, in seconds
--socket-timeout 10

# Download only videos not listed in the archive file. Record the IDs of all downloaded videos in it.
#--download-archive   /path/archive.txt

# Number of retries (default is 10), or "infinite".
--retries infinite

# Give these arguments to the external downloader
--external-downloader aria2c  --external-downloader-args "--no-conf -c"

# Output filename template, see the "OUTPUT TEMPLATE" for all the info
-o '~/Videos/%(id)s.%(ext)s'

# Write thumbnail image to disk
#--write-thumbnail

# download best 30hz mp4 file , h264+aac ,use http or https protocol,because we can use aria2c downloader to have a faster speed
--format '(bestvideo[ext=mp4][fps<31]+bestaudio[ext=m4a]/best[ext=mp4]/bestvideo+bestaudio/best)[protocol^=http]'

# Embed thumbnail in the audio as cover art
#--embed-thumbnail

# Write metadata to the video file
--add-metadata

curl

简介

curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。

它的功能非常强大,命令行参数多达几十种。如果熟练的话,完全可以取代 Postman 这一类的图形界面工具。

本文介绍它的主要命令行参数,作为日常的参考,方便查阅。

不带有任何参数时,curl 就是发出 GET 请求。

curl https://www.example.com

上面命令向www.example.com发出 GET 请求,服务器返回的内容会在命令行输出。

主要命令行参数

-A

-A参数指定客户端的用户代理标头,即User-Agent。curl 的默认用户代理字符串是curl/[version]

curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' https://google.com

上面命令将User-Agent改成 Chrome 浏览器。

curl -A '' https://google.com

上面命令会移除User-Agent标头。

也可以通过-H参数直接指定标头,更改User-Agent

curl -H 'User-Agent: php/1.0' https://google.com

-b

-b参数用来向服务器发送 Cookie。

curl -b 'foo=bar' https://google.com

上面命令会生成一个标头Cookie: foo=bar,向服务器发送一个名为foo、值为bar的 Cookie。

curl -b 'foo1=bar;foo2=bar2' https://google.com

上面命令发送两个 Cookie。

curl -b cookies.txt https://www.google.com

上面命令读取本地文件cookies.txt,里面是服务器设置的 Cookie(参见-c参数),将其发送到服务器。

-c

-c参数将服务器设置的 Cookie 写入一个文件。

curl -c cookies.txt https://www.google.com

上面命令将服务器的 HTTP 回应所设置 Cookie 写入文本文件cookies.txt

-d

-d参数用于发送 POST 请求的数据体。

$ curl -d 'login=emma&password=123'-X POST https://google.com/login
# 或者
$ curl -d 'login=emma' -d 'password=123' -X POST  https://google.com/login

使用-d参数以后,HTTP 请求会自动加上标头Content-Type : application/x-www-form-urlencoded。并且会自动将请求转为 POST 方法,因此可以省略-X POST

-d参数可以读取本地文本文件的数据,向服务器发送。

curl -d '@data.txt' https://google.com/login

上面命令读取data.txt文件的内容,作为数据体向服务器发送。

–data-urlencode

--data-urlencode参数等同于-d,发送 POST 请求的数据体,区别在于会自动将发送的数据进行 URL 编码。

curl --data-urlencode 'comment=hello world' https://google.com/login

上面代码中,发送的数据hello world之间有一个空格,需要进行 URL 编码。

-e

-e参数用来设置 HTTP 的标头Referer,表示请求的来源。

curl -e 'https://google.com?q=example' https://www.example.com

上面命令将Referer标头设为https://google.com?q=example

-H参数可以通过直接添加标头Referer,达到同样效果。

curl -H 'Referer: https://google.com?q=example' https://www.example.com

-F

-F参数用来向服务器上传二进制文件。

curl -F 'file=@photo.png' https://google.com/profile

上面命令会给 HTTP 请求加上标头Content-Type: multipart/form-data,然后将文件photo.png作为file字段上传。

-F参数可以指定 MIME 类型。

curl -F 'file=@photo.png;type=image/png' https://google.com/profile

上面命令指定 MIME 类型为image/png,否则 curl 会把 MIME 类型设为application/octet-stream

-F参数也可以指定文件名。

curl -F 'file=@photo.png;filename=me.png' https://google.com/profile

上面命令中,原始文件名为photo.png,但是服务器接收到的文件名为me.png

-G

-G参数用来构造 URL 的查询字符串。

curl -G -d 'q=kitties' -d 'count=20' https://google.com/search

上面命令会发出一个 GET 请求,实际请求的 URL 为https://google.com/search?q=kitties&count=20。如果省略--G,会发出一个 POST 请求。

如果数据需要 URL 编码,可以结合--data--urlencode参数。

curl -G --data-urlencode 'comment=hello world' https://www.example.com

-H

-H参数添加 HTTP 请求的标头。

curl -H 'Accept-Language: en-US' https://google.com

上面命令添加 HTTP 标头Accept-Language: en-US

curl -H 'Accept-Language: en-US' -H 'Secret-Message: xyzzy' https://google.com

上面命令添加两个 HTTP 标头。

curl -d '{"login": "emma", "pass": "123"}' -H 'Content-Type: application/json' https://google.com/login

上面命令添加 HTTP 请求的标头是Content-Type: application/json,然后用-d参数发送 JSON 数据。

-i

-i参数打印出服务器回应的 HTTP 标头。

curl -i https://www.example.com

上面命令收到服务器回应后,先输出服务器回应的标头,然后空一行,再输出网页的源码。

-I

-I参数向服务器发出 HEAD 请求,然会将服务器返回的 HTTP 标头打印出来。

curl -I https://www.example.com

上面命令输出服务器对 HEAD 请求的回应。

--head参数等同于-I

curl --head https://www.example.com

-k

-k参数指定跳过 SSL 检测。

curl -k https://www.example.com

上面命令不会检查服务器的 SSL 证书是否正确。

-L

-L参数会让 HTTP 请求跟随服务器的重定向。curl 默认不跟随重定向。

curl -L -d 'tweet=hi' https://api.twitter.com/tweet

–limit-rate4

--limit-rate用来限制 HTTP 请求和回应的带宽,模拟慢网速的环境。

curl --limit-rate 200k https://google.com

上面命令将带宽限制在每秒 200K 字节。

-o

-o参数将服务器的回应保存成文件,等同于wget命令。

curl -o example.html https://www.example.com

上面命令将www.example.com保存成example.html

-O

-O参数将服务器回应保存成文件,并将 URL 的最后部分当作文件名。

curl -O https://www.example.com/foo/bar.html

上面命令将服务器回应保存成文件,文件名为bar.html

-s

-s参数将不输出错误和进度信息。

curl -s https://www.example.com

上面命令一旦发生错误,不会显示错误信息。不发生错误的话,会正常显示运行结果。

如果想让 curl 不产生任何输出,可以使用下面的命令。

curl -s -o /dev/null https://google.com

-S

-S参数指定只输出错误信息,通常与-s一起使用。

curl -s -o /dev/null https://google.com

上面命令没有任何输出,除非发生错误。

-u

-u参数用来设置服务器认证的用户名和密码。

curl -u 'bob:12345' https://google.com/login

上面命令设置用户名为bob,密码为12345,然后将其转为 HTTP 标头Authorization: Basic Ym9iOjEyMzQ1

curl 能够识别 URL 里面的用户名和密码。

curl https://bob:12345@google.com/login

上面命令能够识别 URL 里面的用户名和密码,将其转为上个例子里面的 HTTP 标头。

curl -u 'bob' https://google.com/login

上面命令只设置了用户名,执行后,curl 会提示用户输入密码。

-v

-v参数输出通信的整个过程,用于调试。

curl -v https://www.example.com

--trace参数也可以用于调试,还会输出原始的二进制数据。

curl --trace - https://www.example.com

-x

-x参数指定 HTTP 请求的代理。

curl -x socks5://james:cats@myproxy.com:8080 https://www.example.com

上面命令指定 HTTP 请求通过myproxy.com:8080的 socks5 代理发出。

如果没有指定代理协议,默认为 HTTP。

curl -x james:cats@myproxy.com:8080 https://www.example.com

上面命令中,请求的代理使用 HTTP 协议。

-X

-X参数指定 HTTP 请求的方法。

curl -X POST https://www.example.com

上面命令对https://www.example.com发出 POST 请求。

HTTPie

HTTPie(http)以一种更人性化的方式做同样的工作。你会看到彩色的、格式化的输出,这使得它更容易理解和调试。

axel

Lightweight CLI download accelerator

USENET

起源

简单地说,USENET是一个巨大无比的网上讨论组,一般也称为"新闻组"(newsgroups)。你可以将它想象成一个包罗万象、无所不有的网上论坛,但是它又不同于我们通常看到的普通论坛。这要从它的起源说起。

上个世纪70年代末,当时还没有互联网和浏览器,它们都要在十多年后才会出现。那时所谓"上网",就是用modem(调制解调器),拨一个电话号码,将自己的电脑连到另一台电脑(也称"主机"),收收邮件,看看上面系统管理员发的通告。如果想换一台主机看看,那就必须先挂断,再拨另外一个电话号码。

这样的上网方式,很不利于开展多人的讨论。由于是拨号上网,只有地理位置相近的用户,才会登录同一台主机。很难想象,同一台机器的登录用户,既有东岸的纽约人,也有西岸的洛杉矶人。即使长途电话费不是问题,当时的主机也没有能力同时负担太多的远程终端。因此,迫切需要一种大规模的、分布式的、多中心的远程信息交换手段。

1979年,Duke大学的两个研究生Tom Truscott和Jim Ellis,提出一种分布式的网上讨论组的构想。这种讨论组创建之初,主要是供UNIX爱好者协会(USENIX)的成员使用,因此就被定名为USENET。当然,后来全世界的用户都在使用它。

运行机制

USENET的运行机制其实非常简单。对于用户来说,只有三步。

1)网络服务提供商(ISP)在一个网络中,设定一台服务器作为USENET专用服务器,再将它的网址告诉用户。

2)用户想要发言的时候,就向这个网址发送帖子(post),这与发送Email很相似,但是两者格式不一样,在USENET上发言必须使用专用的客户端。不过,现在大多数的Email客户端都带有新闻组功能,最常见的Outlook Express的设置可以参考网上的说明。

3)查看其他人的发言时,就必须从服务器上下载其他人的帖子。下载完成后,如果想回复某人的帖子,就再重复第二步。

可以看到,这个过程同邮件列表的运行几乎一模一样,不同之处在于,USENET服务器每天会同其他USENET服务器交换帖子。这就是说,全世界所有的USENET服务器最终都可以互相交换帖子,保持内容的同步。所以理论上,不管你的帖子是发到哪一台服务器上,最终全世界的人们都会看到,并且会从世界各地给你回复。

因此,USENET就有一个其他交流机制所没有的优点,即这是一个真正的全世界参与的讨论组。

内容结构

由于USENET中的讨论内容无所不包,所以必须根据主题分类。每一个主题就是一个"频道",对这个主题感兴趣的用户就订阅这个频道。

USENET中的主题分类采用等级制(hierarchies),在形式上同域名很相似,即"一级主题.二级主题.三级主题….",中间以小数点分隔。

一级主题有9个。

* comp.*: 与计算机相关的讨论。(computer-related discussions,比如comp.software, comp.sys.amiga)

* misc.*: 各种不属于其他分类的主题。(Miscellaneous topics,比如misc.education, misc.forsale, misc.kids)

* news.*: 对USENET本身的讨论(比如news.groups, news.admin)

* rec.*: 休闲和娱乐(Recreation and entertainment,比如rec.music, rec.arts.movies)

* sci.*: 与科学相关的讨论。(Science related discussions,比如sci.psychology, sci.research)

* soc.*: 与社会相关的讨论。(Social discussions,比如soc.college.org, soc.culture.african)

* talk.*: 各种争议性话题的讨论。(Talk about various controversial topics,比如talk.religion, talk.politics, talk.origins)

* humanities.*: 艺术、文学、哲学方面的讨论。(Fine arts, literature, and philosophy,比如humanities.classics, humanities.design.misc)

* alt.*: 自由讨论区。(alternative)

这9个一级主题中,除了alt.*以外,都不能自行设立讨论区。只有在alt主题区中,可以自己发起主题"频道"。

二进制内容

USENET最初设计的时候,只打算用来传递文本信息,没有考虑传递二进制数据(也就是"文件")。但是,随着互联网的发展,不传递二进制数据看上去是不可能的。

于是,专门的编码方式被设计了出来,使得二进制文件可以转换成文本文件,在USENET上传递,用户下载以后再传换成原来的格式。这时,USENET就不仅是一个讨论组了,而成了传递文件的一种手段,图片、音频和视频都可以通过USENET传播。

事实上,如今USENET上的流量,99%都已经是二进制文件了。它们大部分都在alt.binaries这个主题中传播。由于不受监管,所以各种各样的文件都有。

收费服务

根据一项统计,2007年4月USENET上一天的流量为3.12TB,且还在快速增加中。这么大的流量,使得世界上提供USENET的服务商肯定不会很多。大家可以查看这个网页,上面有USENET提供商的不完全列表。

这些服务商,又分为免费和收费两种。免费的USENET绝大多数都不提供二进制文件下载,查看alt.free.newsservers主题可以获得最新的免费USENET服务器的信息。

在收费服务商中,名气比较大的是GIGANEWS,它提供多种收费账户供用户选择。其中白金用户每月费用为19.99美元,可以无限量下载,14天内不满意可以退款。如果你是一个狂热的下载爱好者,我强烈推荐去购买一个账户。

Google Groups

Google Groups也提供免费USENET服务。(当然,没有二进制文件下载。)我会另写文章专门介绍,这里就省略了。

百度网盘

阿里云盘小白羊版

BaiduPCS-Go

坚果云

xdm

Powerfull download accelerator and video downloader

Motrix

A full-featured download manager.

Thunder

flatpak 版迅雷下载,用于下载 ed2k 链接。

Editor

修改預設 editor

visudo 等操作会打开默认编辑器,在linux中默认编辑器读取EDITOR环境变量,可通过一下命令设置

export EDITOR=nano

可将其加入~/.bashrc文件,使得每次登录都可使用

$ nano ~/.bashrc
export EDITOR=nano
$ . ~/.bashrc

debian系统提供了一个管理工具来设置默认编辑器。執行下面的指令,就可以設定改用其他慣用的文字編輯器了。

sudo update-alternatives --config editor

會出現一個類似如下的列表,選擇你預設要使用的文字編輯器就行了。

There are 5 choices for the alternative editor (providing /usr/bin/editor).

  Selection    Path                Priority   Status
------------------------------------------------------------
* 0            /bin/nano            40        auto mode
  1            /bin/ed             -100       manual mode
  2            /bin/nano            40        manual mode
  3            /usr/bin/nvim        30        manual mode
  4            /usr/bin/vim.basic   30        manual mode
  5            /usr/bin/vim.tiny    15        manual mode

Press <enter> to keep the current choice[*], or type selection number:

我輸入「3」,按下「Enter」。

上面的操作完畢後驗證一下,看看是不是你想要預設使用的編輯器。

執行下面的指令

editor

或是執行下面的指令

sensible-editor

另外也可以直接執行下面的指令,更改成你慣用的文字編輯器

例如:

慣用 vim.tiny

sudo update-alternatives --set editor /usr/bin/vim.tiny

VSCode

Alternatively, the repository and key can also be installed manually with the following script:

sudo apt-get install wget gpg
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
sudo install -D -o root -g root -m 644 packages.microsoft.gpg /etc/apt/keyrings/packages.microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list'
rm -f packages.microsoft.gpg

Then update the package cache and install the package using:

$ sudo apt install apt-transport-https
$ sudo apt update
$ sudo apt install code # or code-insiders
$ cat /usr/share/applications/code.desktop 
[Desktop Entry]
Name=Visual Studio Code
Comment=Code Editing. Redefined.
GenericName=Text Editor
Exec=/usr/share/code/code --unity-launch %F
Icon=com.visualstudio.code
Type=Application
StartupNotify=false
StartupWMClass=Code
Categories=TextEditor;Development;IDE;
MimeType=text/plain;inode/directory;application/x-code-workspace;
Actions=new-empty-window;
Keywords=vscode;

[Desktop Action new-empty-window]
Name=New Empty Window
Exec=/usr/share/code/code --new-window %F
Icon=com.visualstudio.code

GitHub VS Code Web

只要访问下面的网址,你就能在浏览器里面,使用 VS Code 编辑指定仓库。

https://github.dev/[用户名]/[仓库名]

它实际上就是 VS Code 编辑器的 Web 版,并且与 Git 高度集成。

国内下载速度慢

使用 azure 中国 cdn 镜像地址加速下载 VSCode

默认下载地址替换为 vscode.cdn.azure.cn

code-server

VS Code in the browser

可以提高兼容性,解决输入法之类的问题。

配置

Press CTRL+SHIFT+P, then search for

Open User Settings (JSON)

{
    // 每80和120行就显示一条线
    "editor.rulers": [
        80,
        120
    ],
    // 失去焦点后自动保存
    "files.autoSave": "onFocusChange",
    // 每次保存的时候自动格式化
    "editor.formatOnSave": true,
    // 缩进
    "editor.tabSize": 4,
    "editor.insertSpaces": true,
    "editor.detectIndentation": false,
    // 自动换行
    "editor.wordWrap": "off",
    // 字体
    "editor.fontFamily": "'Meslo LG S for Powerline', monospace",
    "editor.fontSize": 14,
    // Folding Maximum Regions
    "editor.foldingMaximumRegions": 50000,

Open Keyboard Shortcuts (JSON)

// Place your key bindings in this file to override the defaults
[
    {
        "key": "ctrl+shift+u",
        "command": "editor.action.transformToUppercase",
        "when": "editorTextFocus"
    },
    {
        "key": "ctrl+shift+l",
        "command": "editor.action.transformToLowercase",
        "when": "editorTextFocus"
    }
]

参考:

快捷键

对于 行 的操作:

  • 重开一行:光标在行尾的话,回车即可;不在行尾,ctrl + enter 向下重开一行;ctrl+ shift + enter 则是在上一行重开一行
  • 删除一行:光标没有选择内容时,ctrl + x 剪切一行;ctrl + shift + k 直接删除一行
  • 移动一行:alt + ↑ 向上移动一行;alt + ↓ 向下移动一行
  • 复制一行:shift + alt + ↓ 向下复制一行;shift + alt + ↑ 向上复制一行
  • ctrl + z 回退

对于 词 的操作:

  • 选中一个词:ctrl + d

搜索或者替换:

  • ctrl + f :搜索
  • ctrl + alt + f: 替换
  • ctrl + shift + f:在项目内搜索

通过 Ctrl + ` 可以打开或关闭终端

Ctrl+P 快速打开最近打开的文件

Ctrl+Shift+N 打开新的编辑器窗口

Ctrl+Shift+W 关闭编辑器

Home 光标跳转到行头

End 光标跳转到行尾

Ctrl + Home 跳转到页头

Ctrl + End 跳转到页尾

Ctrl + Shift + [ 折叠区域代码

Ctrl + Shift + ] 展开区域代码

Ctrl + / 添加关闭行注释

Shift + Alt +A 块区域注释

插件

  • open in browser:运行html文件
  • Auto Rename Tag:自动修改匹配的 HTML 标签。
  • VS Code Hex Editor

Truste folders

Using a single trusted folder to hold your projects

If you work with many projects that you trust and don’t want to be prompted about trusting each one individually, you can consider trusting their parent folder.

  1. Using Ctrl + Shift + P run the Workspaces: Manage Workspace Trust command
  2. Scroll down to the Trusted folders and workspaces section and click Add Folder
  3. Select the parent folder of all your trusted workspaces

Now any project you open under the parent folder will be trusted automatically.

Google Keep

web version.

Google Keep键盘快捷键

hortcut Action
J/K Next/previous note
Shift + J/K Move note to next/previous position
N/P Next/previous list item
Shift + N/P Move list item to next/previous position
C New note
L New list
/ Search
Ctrl + A Select all
E Archive
# Delete
F Pin/unpin
X Select
Ctrl + G Toggle list and grid view
Esc Close editor
Ctrl + Shift + 8 Toggle checkboxes
Ctrl + ] / [ Indent/dedent list item
? Open shortcut list
@ Send feedback

Joplin

wget -O - https://raw.githubusercontent.com/laurent22/joplin/dev/Joplin_install_and_update.sh | bash

joplin.desktop

[Desktop Entry]
Encoding=UTF-8
Name=Joplin
Comment=Joplin for Desktop
Exec=${HOME}/.joplin/Joplin.AppImage ${SANDBOXPARAM} %u
Icon=joplin
StartupWMClass=Joplin
Type=Application
Categories=Office;
MimeType=x-scheme-handler/joplin;
X-GNOME-SingleWindow=true // should be removed eventually as it was upstream to be an XDG specification
SingleMainWindow=true

为知笔记

notion

思源笔记

备份盘 & 同步盘

备份盘:

同步盘:

Obsidian

闭源软件,但超好用。

最适合程序员的笔记软件

程序员的笔记软件,应该满足下面几个条件。

  • 跨平台,同时支持桌面电脑(Windows,Mac,Linux)和手机(Android,iOS)。
  • 随时同步,打开任何一台机器,都能接着上一次的工作继续写。
  • 实时存储,如果软件突然关闭,也不会丢失内容。
  • 支持 Markdown 格式,便于后期直接发布。
  • 支持推送到远程 Git 仓库,产生历史版本,同时作为远程备份。

Stackedit.ioHackMD.io,都不是很理想。

GitHub 官方推出的 github.dev。只要访问 https://github.dev/[用户名]/[仓库名],你就能在浏览器里面,使用 VS Code 编辑指定仓库。它实际上就是 VS Code 编辑器的 Web 版,并且与 Git 高度集成。GitHub 提供了一个快捷入口。 打开 GitHub 仓库主页,按一下小数点(.)这个键, 页面就会自动跳转到 VS Code 编辑环境。

如果你更希望使用手机原生 App,我推荐 Obsidian。它有全平台的客户端,并且可以参考这篇文章设置 Git 集成。

评论里还有很多推荐,选择一个合适的就行。

安装

使用 AppImage 报 dlopen(): error loading libfuse.so.2 错误:

sudo apt install libfuse2

全平台同步

remotely-save

remotely-save 用于 Android 端与 PC 端的同步,可使用 dropbox。我希望在每次关闭 Obsidian 窗口(即编辑完毕后)自动备份内容到 Git 仓库。

  • obsidian.desktop

    [Desktop Entry]
    Name=Obsidian
    GenericName=Markdown Editor
    Exec=/home/kurome/.opt/obsidian/obsidian %U
    Icon=obsidian
    Type=Application
    StartupNotify=true
    Categories=Office;WordProcessor;
    MimeType=x-scheme-handler/obsidian;text/html;text/markdown;text/x-markdown;
    
  • obsidian

    #!/usr/bin/bash
    TIME="$(date '+%Y%m%d%H%M%S')"
    NOTEON=$HOME/Documents/Note_ON
    
    function Git_Sync() {
      cd $NOTEON
      echo "====== PULL ======"
      git pull
      echo '#Ignore files larger than 100MB'
      cat .gitignore_default > .gitignore
      find . -size +100M | sed 's|^./||g' | cat >> .gitignore
      git add .
      git commit -m "Update-${TIME}"
      echo "====== PUSH ======"
      git push -v
    }
    
    /home/kurome/.opt/obsidian/Obsidian-0.15.6.AppImage
    
    trap Git_Sync EXIT
    

比较常遇到的问题是有时候分别点击PC端与Android端的同步后,会以PC端为主,将Android端的修改抹除掉。

obsidian-git

这个方案完全使用 git,在 Android 端也不需要额外的 git 客户端。根据官方教程进行安装:

Follow these instructions for setting up an Obsidian Vault on a mobile device that is already backed up in a remote git repository.

The instructions assume you are using GitHub, but can be extrapolated to other providers.

  1. Make sure any outstanding changes on all devices are pushed and reconciled with the remote repo.
  2. Install Obsidian for Android or iOS.
  3. Create a new vault (or point Obsidian to an empty directory). Do NOT select Store in iCloud if you are on iOS.
  4. If your repo is hosted on GitHub, authentication must be done with a personal access token. Detailed instruction for that process can be found here. Minimal permissions required are “Read access to metadata” and “Read and Write access to contents and commit status” for the repo you are going to use.
  5. In Obsidian settings, enable community plugins. Browse plugins to install Obsidian Git.
  6. Enable Obsidian Git (on the same screen)
  7. Go to Options for the Obsidian Git plugin (bottom of main settings page, under Community Plugins section)
  8. Under the “Authentication/Commit Author” section, fill in the username on your git server and your password/personal access token.
  9. Leave the relative path setting empty (for advanced users only).
  10. Exit plugin settings, open command palette, choose “Obsidian Git: Clone existing remote repo”.
  11. Fill in repo URL in the text field and press the repo URL button below it. The repo URL is NOT the URL in the browser. You have to append .git.
  12. Follow instructions to determine the folder to place repo in and whether an .obsidian directory already exits.
  13. Clone should start. Popup notifications (if not disabled) will display the progress. Do not exit until a popup appears requesting that you “Restart Obsidian”.

使用的时候只需要下拉打开 command palette,然后输入 commitpush 等就行。

如果产生 Conflict,而手机端没有完全体的 Git,则需要重新 Clone ,这样还没有 remotely-save 好。

补充文章

Typora

安装:

# sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BA300B7755AFCFAE
$ wget -qO - https://typora.io/linux/public-key.asc | $ sudo apt-key add -
# add Typora's repository
$ sudo add-apt-repository 'deb https://typora.io/linux ./'
$ sudo apt-get update
# install typora
$ sudo apt-get install typora

如果安装的时二进制包,则建立 typora.desktop

$ gedit ~/.local/share/applications/typora.desktop
[Desktop Entry]
Name=Typora
Comment=a minimal Markdown reading & writing app. Change Log: (https://typora.io/windows/dev_release.html)
GenericName=Markdown Editor
Exec=/home/kurome/.opt/typora/Typora %U
Icon=typora
Type=Application
StartupNotify=true
Categories=Office;WordProcessor;
MimeType=text/markdown;text/x-markdown;

typora 有时会出现丢数据的现象,很困扰;特别是围栏代码块,失去了缩进,成了一行,完全不可阅读了。但是其他的 Markdown Editor 用的不习惯,例如 VSCode、Sublime、ghostwriter、marktext。因此最好通过 ppa 安装,获取 Typora 最新的版本。

在Joplin下,菜单Tools->Options->General>Text editor command可以设置第三方编辑软件。

配置 File > Preferences

  • General > Auto Save: on
  • Editor > Spell Check: Disable
  • Image > Use relative path if possible: on
  • Markdown > Syntax Support > Inline Math: on

有时候标点符号没有与文字对齐,比如句号在右中,而不是右下,可以将语言设置为中文(it works for me)。

Can I use Typora for free ?

You will have a 15-day free trial before the purchase. If you use the dev version or the Linux version, you will have much longer trial time if you keep Typora updated. However, we may show a “trial button”, disable certain features or shorten trial time in the future, but most functions will be kept.

Typora’s pricing plan

It is one-time payment, not subscription.

A Typora license is granted to the “user”, which can be activated on up to 3 devices from one person for one license with no expiration time.

You will have 15 days to evaluate Typora for free before purchasing a license code. If you’re not satisfied with Typora for any reason, you will be able to get a full refund within 30 days from the license purchase.

Recover Unsaved Drafts

Preferences => General => Save & Recover => Recover Unsaved Drafts => 选择要恢复的文档,打开后另存为到之前保存的地址覆盖它即可

Ctrl 5 of typora does not work

不知道哪里覆盖了。重新定义一个快捷键。

Open MenuPreference in Typora, then click “Open Advanced Settings”.

"keyBinding": {
    "Heading 5": "Alt+5",
},

主题推荐

GitHub 主题,很习惯了:

MarkText

Foxit PDF Reader

Industry’s most powerful PDF reader.

Portable PDF Unlocker/PDFCrack

Print the Secured PDF in Google Chrome

有的用户虽然记得PDF文档的密码,但由于经常使用这个PDF文档,为了方便使用也想将这个密码去除。而去除的方法也非常简单,用最常见的谷歌浏览器就可以做到。首先运行谷歌浏览器,将需要去除密码的PDF文档拖曳进浏览器窗口。这时会弹出一个对话框,输入相应的密码就可以看到内容。接着在文档内容中点击鼠标右键,选择菜单里面的“打印”命令。

在弹出的打印窗口点击左侧“目标”中的“更改”按钮,在弹出的对话框中选择“本地目标”中的“另存为PDF”命令。返回到打印窗口后直接点击“保存”按钮,在弹出的对话框里面设置文档的保存位置,再点击“保存”按钮就会将当前的PDF文档另外存储一份,这样也就相当于去除了PDF文档的密码了。

Online PDF Password Remover

**How to Unlock A PDF for Editing Without Password? [Five Methods]**

pdftk

给 pdf 电子书加目录

对许多人来说 pdf 格式的电子书最头疼的两件事: → 1) 每页都是没经过 OCR 处理过的图片 2) 没有目录。

以下这个批量加目录的方法我用好久了,见过我这么操作过的都想学一下,这里详细地记录以下,也方便以后有人再问的时候 :)

用到的软件是 pdftk pdftk-java 。linux 发行版一般都有这个这个软件可以直接安装。

pdftk 的用法就是:输出 (dump_data) pdf 的元信息 (data.txt),编辑以后,重新倒入 (update_info) 到 pdf 文件里面

主要是这两条命令:

pdftk [my.pdf] dump_data > [data.txt]
pdftk [my.pdf] update_info [data.txt] output my2.pdf

在第一条命令输出的 data.txt 里面加入如下的内容,然后通过第二条命令就可以创建新的目录条目

BookmarkBegin
BookmarkTitle: name
BookmarkLevel: level
BookmarkPageNumber: page number

另外电子书的第一页通常是封面,紧接着的是其它的东西。但是书里面标注的页码的第一页往往后面的某页。

PDF 支持把页码标注成其它的格式 (page_labels),第一页标注成 cover,第二到第十页标注成罗马数字,然后从第十一页标注成 1,2,3,4,5,6…

# 把第一页标注成名字为 cover 的非数字 (NoNumber)
PageLabelBegin
PageLabelNewIndex: 1
PageLabelStart: 1
PageLabelPrefix: cover
PageLabelNumStyle: NoNumber

# 从第二页 (PageLabelNewIndex) 开始标注成小写罗马数字 (LowercaseRomanNumerals)
PageLabelBegin
PageLabelNewIndex: 2
PageLabelStart: 1 # 从数字 1 开始数,如果这里变成 3  => 起始的罗马数字会是 iii
PageLabelNumStyle: LowercaseRomanNumerals

# 从 {true start page} 开始用普通的数字标注
PageLabelBegin
PageLabelNewIndex: {true start page}
PageLabelStart: 1
PageLabelNumStyle: DecimalArabicNumerals

对于一本书,这种手动添加的方法会很慢,下面是一个小脚本来半自动化。


由于电子书 100% 可以搜索到目录 编号 标题 页码。如果搜索不到,也可以直接从书里面复制。

复制粘贴一下,调整成这种格式

14
I: Reduction Semantics 1
 1 Semantics via Syntax 5
 2 Analyzing Syntactic Semantics 13
 3 The λ-Calculus 23
 4 ISWIM 45
II: PLT Redex 201
 11 The Basics 205
 12 Variables and Meta-functions 217
 13 Layered Development 227
 14 Testing 237
......

第一行是对于人类,而非 pdf 格式来说真正的第一页

后面根据行首 tab 的数量来决定目录的层级

每行后面的数字是页码

然后用这个小脚本 toc-gen.py

#!/usr/bin/env python3

#
# Usage
# toc-gen.py  < edited-toc.txt
#

def make_offset(off: int):
    if off > 1:
        print("""PageLabelBegin
PageLabelNewIndex: 1
PageLabelStart: 1
PageLabelPrefix: cover
PageLabelNumStyle: NoNumber""")

    if off > 2:
        print("""PageLabelBegin
PageLabelNewIndex: 2
PageLabelStart: 1
PageLabelNumStyle: LowercaseRomanNumerals""")

    print(f"""PageLabelBegin
PageLabelNewIndex: {off}
PageLabelStart: 1
PageLabelNumStyle: DecimalArabicNumerals""")


def make_bookmark(t: str, l: int, p: int):
    print(f"""BookmarkBegin
BookmarkTitle: {t}
BookmarkLevel: {l}
BookmarkPageNumber: {p}""")


if __name__ == '__main__':
    offset = int(input())
    make_offset(offset)
    while True:
        try:
            line = input()
            if not line.strip():
                break
        except EOFError:
            break

        title = " ".join(line.split()[0:-1])
        n_of_tabs = len(line) - len(line.lstrip())
        page = int(line.split()[-1])

        make_bookmark(t=title,
                      l=n_of_tabs + 1,
                      p=page + offset)

来获取这些内容,把这些内容粘贴到 [data.txt] 后面,然后再用 pdftk 的第二条命令

PageLabelBegin
PageLabelNewIndex: 1
PageLabelStart: 1
PageLabelPrefix: cover
PageLabelNumStyle: NoNumber
PageLabelBegin
PageLabelNewIndex: 2
PageLabelStart: 1
PageLabelNumStyle: LowercaseRomanNumerals
PageLabelBegin
PageLabelNewIndex: 14
PageLabelStart: 1
PageLabelNumStyle: DecimalArabicNumerals
BookmarkBegin
BookmarkTitle: Reduction Semantics
BookmarkLevel: 1
BookmarkPageNumber: 15
BookmarkBegin
BookmarkTitle: Semantics via Syntax
BookmarkLevel: 2
BookmarkPageNumber: 19
BookmarkBegin
BookmarkTitle: Analyzing Syntactic Semantics
BookmarkLevel: 2
BookmarkPageNumber: 27
BookmarkBegin
BookmarkTitle: The λ-Calculus
BookmarkLevel: 2
BookmarkPageNumber: 37
BookmarkBegin
BookmarkTitle: ISWIM
BookmarkLevel: 2
BookmarkPageNumber: 59
BookmarkBegin
BookmarkTitle: An Abstract Syntax Machine
BookmarkLevel: 2
BookmarkPageNumber: 79
BookmarkBegin
BookmarkTitle: Abstract Register Machines
BookmarkLevel: 2
BookmarkPageNumber: 103
BookmarkBegin
BookmarkTitle: Tail Calls and More Space Savings
BookmarkLevel: 2
BookmarkPageNumber: 121
BookmarkBegin
BookmarkTitle: Control: Errors, Exceptions, and Continuations
BookmarkLevel: 2
BookmarkPageNumber: 129
BookmarkBegin
BookmarkTitle: State: Imperative Assignment
..............

Bingo! 这下舒服了 :)

Tesseract

Tesseract Open Source OCR Engine

更多 OCR 软件请看:Comparison of optical character recognition software

Evaluation:An analysis of the accuracy and reliability of the OCR packages Google Docs OCR, Tesseract, ABBYY FineReader, and Transym, employing a dataset including 1227 images from 15 different categories concluded Google Docs OCR and ABBYY to be performing better than others.

OCRmyPDF

OCRmyPDF adds an OCR text layer to scanned PDF files, allowing them to be searched

PandaOCR

PandaOC/R - 多功能OCR图文识别+翻译+朗读+弹窗+公式+表格+图床+搜图+二维码

gImageReader

A Gtk/Qt front-end to tesseract-ocr.

OCRfeeder

支持多个 OCR 后端,例如TesseractCuneiFormGOCROcrad

tianruoocr

简介:基于天若幽心开源的代码进行完善制作而成,进行了简单重构,移除了更新的弹窗。

已停止维护,欢迎使用新版跨平台 OCR 工具(树洞 OCR 文字识别),跟之前天若OCR使用习惯出入较大,且不支持翻译。

marguerite 答 ORC

我来告诉你什么是 OCR:

OCR 说白了就是,把一个特定字体的某个字变成计算机可匹配的位置数据,比如在 50x50 像素的格子里,「儿」这个字的撇的黑色像素点落在大概 (30~45, 0~100) 这个范围内,然后把图片进行切割细分,得到许多个 50x50 的格子,在这个格子里 (30~45, 0~100) 它有黑色像素点,那么就非常可能是「儿」字。当然也可能是别的字,究竟是什么字,常用汉字就那么多个,这是概率问题。

而 OCR 的重点是:

  1. 字体。你针对宋体的 OCR 训练数据拿到黑体上识别率不见得高。
  2. 训练。所谓的训练就是让计算机匹配时所遵守的概率无限趋近于现实。你可能需要拿出比如 3 万个字(一篇文章),先用默认的识别一遍(这涉及到了「如何根据某个特定字体制作出默认的数据」),然后逐字逐句去挑错,再改进默认数据(这涉及到了「你需要会编程,能够写出一个根据 tesseract 库改数据的软件」),最后越改这个数据越接近现实。

最后才是拿你训练过的数据去进行我上面做过的:

tesseract ./test.png result -l chi_sim

参考、归纳、脑补自:http://miphol.com/muse/2013/05/tesseract-ocr.html

这是 OCR 工作的基本原理和流程,这完全不可能是一个非程序员做的事情,程序员也懒得做这种事情,这是一种苦逼的体力劳动。

Windows 下的 OCR 软件比如微软 word 自带的那个,ABBYY FineReader(这个最好,而且可以 wine)、以及汉王的软件,都是多少苦逼程序员一起,经历了这种枯燥乏味的流程后的结果。

Linux 下的 OCR 软件都是开源的「框架」,比如 tesseract 和你之前问过的 ocropus,它们只是为在 Linux 下进行这种苦逼工作提供了一个基础,提供了可能性,并不是像你要求的那样拿来就能用的东西。因为没有训练过的数据,你安装的中文数据包只是可供你拿来训练的数据。

何况在 Linux 下训练了也没用,OCR 最大的需求是 word 文档转出来的 PDF 和起点网站吧,那些用的字体可不是文泉驿。你现在能够得到的可供训练的数据估计就是 Google 根据 Droid Sans 弄出来的,训练 1 万年也只能识别 Droid Sans,问题是你能把纸面上的字体改了么。想要微软字体的数据?抱歉,微软是商业字体啊。

所以我觉得现在是你对你需求的描述和理解就不对。钻进死胡同了。

WPS

WPS Office is a lightweight, feature-rich comprehensive office suite with high compatibility.

wps-office-appimage

如果进程wpscloudsvr一直运行,占用cpu和内存,可以解包、删除、重打包,或者直接登陆

WPS Fonts

ttf-mscorefonts-installer

ttf-mscorefonts-installer is a Debian package that includes the following set of fonts, and with the help of this installer, you can easily download and use Microsoft’s True core fonts.

  • Andale Mono
  • Arial Black
  • Arial (Bold, Italic, Bold Italic)
  • Comic Sans MS (Bold)
  • Courier New (Bold, Italic, Bold Italic)
  • Georgia (Bold, Italic, Bold Italic)
  • Impact
  • Times New Roman (Bold, Italic, Bold Italic)
  • Trebuchet (Bold, Italic, Bold Italic)
  • Verdana (Bold, Italic, Bold Italic)
  • Webdings
sudo proxychains apt install --reinstall ttf-mscorefonts-installer
sudo fc-cache -vr

ttf-wps-fonts

These are the symbol fonts required by wps-office. They are used to display math formulas. We have collected the fonts here to make things easier.

cd /tmp
git clone https://github.com/iamdh4/ttf-wps-fonts.git
mkdir -p ~/.local/share/fonts/wps-fonts
mv ttf-wps-fonts/* ~/.local/share/fonts/wps-fonts
chmod 644 ~/.local/share/fonts/wps-fonts/*
fc-cache -vfs
rm -rf ttf-wps-fonts

WPS 缺少中文

最近发现了 flatpak 版 wps 没有中文的解决方案:

下载中文版 wps 的包,解压缩后找到里面的 mui 目录,复制到国际版 wps flatpak 的对应目录下,修改一下配置文件,你就得到了中文版 wps

Sublime Text

Atom

Vim

安装 vim ycm 全能补全

sudo apt install -y vim-gtk3 vim-addon-manager vim-youcompleteme vim-python-jedi
vam install youcompleteme python-jedi

然后用 gvim 就有 ycm 智能补全和提示了

vimtutor

Start Vim on a copy of the tutor file.

vi&vim.tiny

$ whereis vi
vi: /usr/bin/vi /usr/share/man/man1/vi.1.gz
$ ls -al /usr/bin/vi
lrwxrwxrwx 1 root root 20 Oct 26 20:31 /usr/bin/vi -> /etc/alternatives/vi
$ ls -al /etc/alternatives/vi
lrwxrwxrwx 1 root root 17 Oct 26 20:31 /etc/alternatives/vi -> /usr/bin/vim.tiny

可见,在Ubuntu上,vi是vim.tiny的软连接,但是执行命令vi与vim.tiny后是不一样,比如vi是:在编辑模式下使用方向键的时候,并不会使光标移动,而是在命令行中出现[A [B [C [D之类的字母;并且编辑错误的话,退格键(Backspace键)是使用不了的。

Methods to find out which (configuration) files are read by executable when started->‘strace vim/nano’ (Ubuntu)

$ strace -o $HOME/tracefile vi
$ cat tracefile | grep vimrc
stat("/usr/share/vim/vimrc.tiny", {st_mode=S_IFREG|0644, st_size=662, ...}) = 0
openat(AT_FDCWD, "/usr/share/vim/vimrc.tiny", O_RDONLY) = 3
stat("/home/vane/.vimrc", 0x7fff3e755550) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/vane/.vimrc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/vane/_vimrc", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/home/vane/.vim/vimrc", 0x7fff3e755550) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/vane/.vim/vimrc", O_RDONLY) = -1 ENOENT (No such file or directory)

可以看到 vi,加载的是 /usr/share/vim/vimrc.tiny

$ strace -o $HOME/tracefile vim.tiny
$ cat tracefile | grep vimrc
stat("/usr/share/vim/vimrc", {st_mode=S_IFREG|0644, st_size=2266, ...}) = 0
openat(AT_FDCWD, "/usr/share/vim/vimrc", O_RDONLY) = 3
stat("/home/vane/.vimrc", 0x7fff7c99cc30) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/vane/.vimrc", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/vane/_vimrc", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/home/vane/.vim/vimrc", 0x7fff7c99cc30) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/vane/.vim/vimrc", O_RDONLY) = -1 ENOENT (No such file or directory)

可以看到 vim.tiny,加载的是 /usr/share/vim/vimrc

$ diff -u /etc/vim/vimrc /etc/vim/vimrc.tiny
--- /etc/vim/vimrc    2020-01-30 19:11:47.000000000 +0800
+++ /etc/vim/vimrc.tiny    2020-04-15 14:40:31.000000000 +0800
@@ -1,55 +1,13 @@
...
+" Vim configuration file, in effect when invoked as "vi". The aim of this
+" configuration file is to provide a Vim environment as compatible with the
+" original vi as possible. Note that ~/.vimrc configuration files as other
+" configuration files in the runtimepath are still sourced.
+" When Vim is invoked differently ("vim", "view", "evim", ...) this file is
+" _not_ sourced; /etc/vim/vimrc and/or /etc/vim/gvimrc are.
...

上面注释什么都说明白了。

link: The missing keybindings etc may be because you are running vim in vi compatible mode - you can turn that off by doing :set nocompatible in vim or adding set nocompatible to you .vimrc file.

set nocompatible

参考 Fedora 默认/etc/virc配置:

set fileencodings=ucs-bom,utf-8,latin1
set nocompatible
set bs=indent,eol,start
set ruler

clear highlighting

:noh

vim.basic&vim.tiny

它们的区别

vim.basic is just plain vanilla Vim (as you can check with apt-file vim.basic or dpkg -S /usr/bin/vim.basic).

While vim.tiny, as the name implies, is a trimmed-down version of Vim (this question explains it further).

vim.tiny --version

VIMRC

The ultimate Vim configuration (vimrc)

copilot.vim

Neovim plugin for GitHub Copilot

Neovim

Neovim 提出了将 Vim 扩展为一个 IDE 的想法。

它增加了现代终端的功能,如光标样式、焦点事件、括号内粘贴等,并内置了一个终端模拟器。最重要的是,你不需要忘却 Vim 的习惯就可以开始使用 Neovim。

现代化Neovim配置

git仓库

除此之外,目前一个比较好的配置是:https://github.com/LunarVim/LunarVim。

vimplus

现代化的vim插件管理工具,开箱即用

ranger

A VIM-inspired filemanager for the console

Color Scheme

自带的 color scheme 都在 /usr/share/vim/vim*/colors 目录下。

:colorscheme 可以显示正在使用的 color scheme

:colorscheme + Space + CTRL-d 显示所有 color scheme

安装 molokai color scheme

mkdir -p ~/.vim/colors
wget -O ~/.vim/colors/molokai.vim https://raw.githubusercontent.com/tomasr/molokai/master/colors/molokai.vim
echo -e "\" Molokai Color Scheme for Vim\nlet g:molokai_original = 1\nlet g:rehash256 = 1\ncolorscheme molokai\n" >> ~/.vimrc

自带主题 slate 也不错。

Font

Console Vim uses whatever font the console/terminal is using. Changing the font in your terminal is done differently depending on your system and the terminal in use. Consult the documentation or manpages for your terminal, or do a web search for how to change the font in your chosen terminal. Vim cannot use a different font than the rest of the terminal.

QA

Why is the cursorline always showing after the cursor moves over a line?

set bg=dark

" highlight current line
set cul                                                                                                                                                     
" adjust color
highlight CursorLine ctermbg=LightBlue cterm=None term=None

How to control/configure vim colors

其实可以直接换个主题。

vim的补全粉色背景色怎么修改呢?

要改变自动补全窗口的配色可以在 vimrc 中加上:

highlight Pmenu    guibg=darkgrey  guifg=black 
highlight PmenuSel guibg=lightgrey guifg=black

Pmenu 是所有项的配色,PmenuSel 是选中项的配色,guibg 和 guifg 分别对应背景色和前景色

Confused about the difference between ‘tabstop’ and ‘shiftwidth’.

tabstop doesn’t necessarily mean that a tab byte (\x09) will be replaced with a number of space bytes (\x20). It’s expandtab that governs whether that happens. tabstop means how long each tabstop will be. set tabstop=8 makes it so that a line starting with a tab byte will appear to be indented 8 character blocks from the left edge of the screen.

shiftwidth governs indentation via » and friends (as said in the docs). set shiftwidth=8 makes it so that each » you do will indent a line 8 character blocks more to the right. Whether it uses tab bytes or space bytes is actually up to a few settings: if noexpandtab is set, it tries its best to use tab bytes alone. If shiftwidth is not divisible by tabstop (e.g. you have set noexpandtab shiftwidth=6 tabstop=4 for some reason), it will use a combination of tabs and spaces to get the proper indent. If expandtab is set, then it will use space bytes alone.

:help shift-left-right is further reading for this: read past the references for the > commands, on to the next few paragraphs where this behavior is explained.

How to tab (back, forward) a block of code in Vim?

  • V select lines by and then >

and for 3 tabs:

  • V, 3 and then >

Shell

Tmux

Tmux 是一个终端复用器(terminal multiplexer),非常有用,属于常用的开发工具。

简介

会话与进程

命令行的典型使用方式是,打开一个终端窗口(terminal window,以下简称"窗口"),在里面输入命令。用户与计算机的这种临时的交互,称为一次"会话"(session) 。

会话的一个重要特点是,窗口与其中启动的进程是连在一起的。打开窗口,会话开始;关闭窗口,会话结束,会话内部的进程也会随之终止,不管有没有运行完。

一个典型的例子就是,SSH 登录远程计算机,打开一个远程窗口执行命令。这时,网络突然断线,再次登录的时候,是找不回上一次执行的命令的。因为上一次 SSH 会话已经终止了,里面的进程也随之消失了。

为了解决这个问题,会话与窗口可以"解绑":窗口关闭时,会话并不终止,而是继续运行,等到以后需要的时候,再让会话"绑定"其他窗口。

Tmux 的作用

Tmux 就是会话与窗口的"解绑"工具,将它们彻底分离。

  1. 它允许在单个窗口中,同时访问多个会话。这对于同时运行多个命令行程序很有用。
  2. 它可以让新窗口"接入"已经存在的会话。
  3. 它允许每个会话有多个连接窗口,因此可以多人实时共享会话。
  4. 它还支持窗口任意的垂直和水平拆分。

类似的终端复用器还有 GNU Screen。Tmux 与它功能相似,但是更易用,也更强大。

基本用法

安装

Tmux 一般需要自己安装。

sudo apt-get install tmux

启动与退出

安装完成后,键入tmux命令,就进入了 Tmux 窗口。

tmux

Tmux 窗口,底部有一个状态栏。状态栏的左侧是窗口信息(编号和名称),右侧是系统信息。

按下Ctrl+d或者显式输入exit命令,就可以退出 Tmux 窗口。

exit

前缀键

Tmux 窗口有大量的快捷键。所有快捷键都要通过前缀键唤起。默认的前缀键是Ctrl+b,即先按下Ctrl+b,快捷键才会生效。

举例来说,帮助命令的快捷键是Ctrl+b ?。它的用法是,在 Tmux 窗口中,先按下Ctrl+b,再按下?,就会显示帮助信息。

然后,按下 ESC 键或q键,就可以退出帮助。

会话管理

新建会话

第一个启动的 Tmux 窗口,编号是0,第二个窗口的编号是1,以此类推。这些窗口对应的会话,就是 0 号会话、1 号会话。

使用编号区分会话,不太直观,更好的方法是为会话起名。

tmux new -s <session-name>

上面命令新建一个指定名称的会话。

分离会话

在 Tmux 窗口中,按下Ctrl+b d或者输入tmux detach命令,就会将当前会话与窗口分离。

tmux detach

上面命令执行后,就会退出当前 Tmux 窗口,但是会话和里面的进程仍然在后台运行。

tmux ls命令或Ctrl+b s可以查看当前所有的 Tmux 会话。

$ tmux ls
# or
$ tmux list-session

接入会话

tmux attach命令用于重新接入某个已存在的会话。

# 使用会话编号
$ tmux attach -t 0
# 使用会话名称
$ tmux attach -t <session-name>

杀死会话

tmux kill-session命令用于杀死某个会话。

# 使用会话编号
$ tmux kill-session -t 0
# 使用会话名称
$ tmux kill-session -t <session-name>

切换会话

tmux switch命令用于切换会话。

# 使用会话编号
$ tmux switch -t 0
# 使用会话名称
$ tmux switch -t <session-name>

重命名会话

tmux rename-session命令或Ctrl+b $用于重命名会话。

tmux rename-session -t 0 <new-name>

上面命令将0号会话重命名。

最简操作流程

综上所述,以下是 Tmux 的最简操作流程。

  1. 在服务器端新建会话tmux new -s my_session
  2. 在 Tmux 窗口运行所需的程序。
  3. 按下快捷键Ctrl+b d将会话分离。
  4. 下次使用时,重新连接到会话tmux attach-session -t my_session

窗格操作

Tmux 可以将窗口分成多个窗格(pane),每个窗格运行不同的命令。以下命令都是在 Tmux 窗口中执行。

划分窗格

tmux split-window命令用来划分窗格。

# 划分上下两个窗格,或 Ctrl+b "
$ tmux split-window
# 划分左右两个窗格,或 Ctrl+b %
$ tmux split-window -h

移动光标

tmux select-pane命令或Ctrl+b <arrow key>用来移动光标位置。

# 光标切换到上方窗格,或 Ctrl+b ;
$ tmux select-pane -U
# 光标切换到下方窗格,或 Ctrl+b o
$ tmux select-pane -D
# 光标切换到左边窗格
$ tmux select-pane -L
# 光标切换到右边窗格
$ tmux select-pane -R
  • Ctrl+b x:关闭当前窗格。
  • Ctrl+b !:将当前窗格拆分为一个独立窗口。
  • Ctrl+b z:当前窗格全屏显示,再使用一次会变回原来大小。
  • Ctrl+b Ctrl+<arrow key>:按箭头方向调整窗格大小。
  • Ctrl+b q:显示窗格编号。

交换窗格位置

tmux swap-pane命令用来交换窗格位置。

# 当前窗格上移,或 Ctrl+b {
$ tmux swap-pane -U
# 当前窗格下移,或 Ctrl+b }
$ tmux swap-pane -D
  • Ctrl+b Ctrl+o:所有窗格向前移动一个位置,第一个窗格变成最后一个窗格。
  • Ctrl+b Alt+o:所有窗格向后移动一个位置,最后一个窗格变成第一个窗格。

窗口管理

除了将一个窗口划分成多个窗格,Tmux 也允许新建多个窗口。

新建窗口

tmux new-window命令用来创建新窗口。

$ tmux new-window
# 新建一个指定名称的窗口
$ tmux new-window -n <window-name>

Ctrl+b c:创建一个新窗口,状态栏会显示多个窗口的信息。

切换窗口

tmux select-window命令用来切换窗口。

# 切换到指定编号的窗口
$ tmux select-window -t <window-number>
# 切换到指定名称的窗口
$ tmux select-window -t <window-name>
  • Ctrl+b p:切换到上一个窗口(按照状态栏上的顺序)。
  • Ctrl+b n:切换到下一个窗口。
  • Ctrl+b <number>:切换到指定编号的窗口,其中的<number>是状态栏上的窗口编号。
  • Ctrl+b w:从列表中选择窗口。

重命名窗口

tmux rename-window命令或Ctrl+b ,用于为当前窗口起名(或重命名)。

tmux rename-window <new-name>

其他命令

下面是一些其他命令。

# 列出所有快捷键,及其对应的 Tmux 命令
$ tmux list-keys
# 列出所有 Tmux 命令及其参数
$ tmux list-commands
# 列出当前所有 Tmux 会话的信息
$ tmux info
# 重新加载当前的 Tmux 配置
$ tmux source-file ~/.tmux.conf

Fish

命令行是程序员的必备技能。图形界面虽然好看,解决问题还是要靠命令行。

命令行由 Shell 提供。各种命令通过 Shell,传递给操作系统的内核。学习命令行就是在学习 Shell。

Shell 有好几种,目前最常用是 Bashzsh。但是,在我看来,它们都不如 Fish Shell 好用。

五年前,我第一次尝试 Fish,感到很惊艳,一直用到现在。本文介绍 Fish 的主要特点,希望你也来尝试它。

简介

Fish 是"the friendly interactive shell"的简称,最大特点就是方便易用。很多其他 Shell 需要配置才有的功能,Fish 默认提供,不需要任何配置。

如果你想拥有一个方便好用的 Shell,又不想学习一大堆语法,或者花费很多时间配置,那么你一定要尝试一下 Fish。

安装

Ubuntu 的安装方法。

sudo apt install fish

其他系统的安装请参考官方网站

启动与帮助

安装完成后,就可以启动 Fish。

fish

由于 Fish 的语法与 Bash 有很大差异,Bash 脚本一般不兼容。因此,我建议不要将 Fish 设为默认 Shell,而是每次手动启动它。

使用过程中,如果需要帮助,可以输入help命令。浏览器就会自动打开,显示在线文档。

help

彩色显示

进入 Fish 以后,你注意到的第一件事,可能就是它默认彩色显示。

# 无效命令为红色
$ mkd

# 有效命令为蓝色
$ mkdir

有效路径会有下划线。

cat ~/somefi 

上面代码表示,存在以~/somefi开头的路径。如果没有下划线,你就知道这个路径不存在。

自动建议

Fish 会自动在光标后面给出建议,表示可能的选项,颜色为灰色。

# 命令建议
$ /bin/hostname

# 参数建议
$ grep --ignore-case

# 路径建议
$ ls node_modules

如果采纳建议,可以按下Control + F。如果只采纳一部分,可以按下Alt + →

自动补全

输入命令时,Fish 会自动显示匹配的上一条历史记录。

git commit -m "feat: first commit"

如果没有匹配的历史记录,Fish 会猜测可能的结果,自动补全各种输入。比如,输入pyt再按下Tab,就会自动补全为python命令。

如果有多个可能的结果,Fish 会把它们都列出,还带有简要介绍。

$ vi[按下 Tab 键]

vi (Executable link, 2.7MB)
view (Vi IMproved, 一个程序员的文本编辑器)
viewer.py (Executable, 967B)
viewres  (Graphical class browser for Xt)
...and 12 more rows

这时,再按一次tab,就可以在这些命令之中选择。

除了补全命令,Fish 还可以补全参数。比如,ls命令的-l参数后面按下Tab键,就会显示可以连用的其他参数。

$ ls -l[按下 Tab 键]

-l1  (List one file per line)
-lA  (Show hidden except . and ..)  
-la  (Show hidden)
-lB  (Ignore files ending with ~)
...and 16 more rows```

Fish 还可以自动补全 Git 分支。

git checkout master

易懂的语法

Fish 的语法非常自然,一眼就能看懂。

if语句:

if grep fish /etc/shells
    echo Found fish
else if grep bash /etc/shells
    echo Found bash
else
    echo Got nothing
end

switch语句:

switch (uname)
case Linux
    echo Hi Tux!
case Darwin
    echo Hi Hexley!
case FreeBSD NetBSD DragonFly
    echo Hi Beastie!
case '*'
    echo Hi, stranger!
end

while循环:

while true
    echo "Loop forever"
end

for循环:

for file in *.txt
    cp $file $file.bak
end

函数

Fish 的函数用来封装命令,或者为现有的命令起别名。

function ll
    ls -lhG $argv
end

上面代码定义了一个ll函数。命令行执行这个函数以后,就可以用ll命令替代ls -lhG。其中,变量$argv表示函数的参数。

下面是另一个例子。

function ls
    command ls -hG $argv
end

上面的代码重新定义ls命令。注意,函数体内的ls之前,要加上command,否则会因为无限循环而报错。

提示符

fish_prompt函数用于定义命令行提示符(prompt)。

function fish_prompt
    set_color purple
    date "+%m/%d/%y"
    set_color FF0
    echo (pwd) '>'
    set_color normal
end

执行上面的函数以后,你的命令行提示符就会变成下面这样。

02/06/13
/home/tutorial > 

配置

Fish 的配置文件是~/.config/fish/config.fish,每次 Fish 启动,就会自动加载这个文件。

我们可以在这个文件里面写入各种自定义函数,它们会被自动加载。比如,上面的fish_prompt函数就可以写在这个文件里面,这样每次启动 Fish,就会出现自定义的提示符。

Fish 还提供 Web 界面配置该文件。

fish_config

输入上面的命令以后,浏览器就会自动打开本机的 8000 端口,用户可以在网页上对 Fish 进行配置,比如选择提示符和配色主题。

Zsh

Oh My Zsh

sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"

oh-my-zsh应该对通配符作了限制,需要用跳脱字符

sudo apt remove fcitx\*

Zsh theme:What’s the best theme for Oh My Zsh?

zsh4humans

Bash

include local bin

$ vim .bashrc
export PATH=/home/kurome/.local/bin:$PATH

bash-git-prompt

$ git clone https://github.com/magicmonty/bash-git-prompt.git ~/.bash-git-prompt --depth=1
$ vim ~/.bashrc
if [ -f "$HOME/.bash-git-prompt/gitprompt.sh" ]; then
    GIT_PROMPT_ONLY_IN_REPO=1
    source $HOME/.bash-git-prompt/gitprompt.sh
fi

bash-completion

一般已经安装配置好了。

awesome-bash

oh-my-bash

不需要 zsh 许多特性,所以可以用这个。

git clone https://github.com/ohmybash/oh-my-bash.git ~/.oh-my-bash
cp ~/.bashrc ~/.bashrc.orig
cp ~/.oh-my-bash/templates/bashrc.osh-template ~/.bashrc
source ~/.bashrc

主题用 powerline,需要下载 Patched fonts for Powerline users,然后在配置中选择 Meslo LG S for Powerline 这一款字体。

Tips

Request root privilege from within a script

This’ll work:

echo "$(whoami)"

[ "$UID" -eq 0 ] || exec sudo "$0" "$@"

How can I run a function from a script in command line?

simply place at the end the special parameter "$@"

if declare -f "$1" > /dev/null
then
  # call arguments verbatim
  "$@"
else
  # Show a helpful error
  echo "'$1' is not a known function name" >&2
  exit 1
fi

How do you list all functions and aliases in a specific script?

declare -F | awk '{print $NF}' | sort | egrep -v "^_" 

Gogh

Color Scheme for your Terminal

bash -c "$(wget -qO- https://git.io/vQgMr)"

我选择的是 VS Code Dark+

Proxy

v2ray

节点准备

简单来讲节点是形如如下的神秘链接:

ss://xxxxxxxxxxxxxxxxxxxxxxxxxxxx
vmess://xxxxxxxxxxxxxxxxxxxxxxxxxxxx

如果你没有这些连接:

  • 自行部署,你则需要自行购买处于自由互联网的服务器并进行节点搭建,这不在本文讨论范围内。如果你需要购买服务器,推荐一个 VPS 提供商:justhost.ru
  • 购买机场的订阅服务,可以参考它们的订阅流程以获取节点。需要提醒的是,机场服务属于灰色产业,随时有停止服务的可能,购买建议以月付进行购买以避免过大损失。关于机场审计规则,我们的观点是"我可以不看,但是你不可以封禁"。对于机场审计程度,读者可根据自身实际情况自行评估。
  • 如果你不想花任何费用,可安装赛风这类软件。它是自由软件。如果你使用赛风,可以非常方便的发送空邮件到get@psiphon3.com以获取赛风下载链接。赛风应用目前只支持 Windows\Android\IOS\MacOS 平台。当你在这些平台上能够访问自由互联网时,可以去各个渠道搜索可用的节点和代理资源。注意,使用公共节点需要自行承担可能的风险。

安装

v2ray/Xray-core 是使用 Qv2ray(原项目已停止开发) 以及 V2rayA 的前提,需要先进行安装。

Qv2ray 和 V2rayA 是两款非常优秀的在 Linux 上可用的科学上网通用客户端:

  • Qv2ray:安装后在 Plugins 中,选择 V2ray Core Plugin,并进行 V2ray 的设置。现在你已经可以使用,你需要按照官方文档导入已有的链接或订阅。
  • V2rayA:2rayA 是一个浏览器客户端,使用非常方便。更多使用方法请看官方文档

代理配置

在经过上述步骤后,你应该已经有了 SOCKS5 代理以及 HTTP 代理的地址和端口。接下来进行设置:

  • 系统代理:在节点链接后,你可在系统设置 -> 网络设置 -> 代理中设置代理。注意,系统设置中的代理配置在 KDE 桌面环境中并不是所有应用都会遵守。没有遵循系统设置代理的应用还需要单独进行代理配置。

  • 终端

    可以通过 export 命令设置当前终端的代理方式。比如使用 tldr 或 github raw 等资源需要设置 https 代理。

    export https_proxy=http://127.0.0.1:8889
    export http_proxy=http://127.0.0.1:8889
    export all_proxy=http://127.0.0.1:8889
    

    不同终端命令所识别的环境变量名不同,如 all_proxy 对 curl 生效,而对 wget 则不生效,具体可查看各个命令的 man page。

  • proxychains/proxychains-ng

    如果对于一个应用,KDE 的系统代理不生效,在终端 export 了 ALL_PROXY 变量再用终端启动此应用代理也不生效,并且这个应用自身也没有配置代理的选项(即应用不支持代理)。此时可以使用 proxychains,它可以为单行命令配置代理,它是一个预加载的 hook,允许通过一个或多个 SOCKS 或 HTTP 代理重定向现有动态链接程序的 TCP 流量(即强制应用走代理)。

    $ sudo apt install proxychains
    $ sudo vim /etc/proxychains.conf
    socks5 127.0.0.1 1089
    

透明代理

全局代理,也即透明代理。之所以叫做透明代理,是因为这代理对于操作系统中的各个应用相当于是透明的,应用们感知不到代理的存在。之所以叫做全局代理,很明显意为全局所有流量都走代理。

  • 在 Qv2ray 的“首选项-入站设置”的下方启用任意门设置选项。

    • 监听 ipv4 地址可填127.0.0.10.0.0.0,建议前者。若需双栈代理,则在监听 ipv6 地址填上::1(如果监听 ipv4 填了 0.0.0.0 则可不填)。
    • 嗅探选择 Full,Destination Override 的三项均勾选。
    • 模式选择“tproxy”。
  • 安装cgproxy软件,编辑/etc/cgproxy/config.json

    • cgroup_proxy中括号里加上"/"port改为 Qv2ray 首选项里的透明代理的端口。
    • cgproxy默认配置是代理所有 tcp 和 udp,ipv4 和 ipv6 的流量,如果不希望代理其中的某种(些)流量,则将对应的enable_xxx改为 false。注意这里的配置要和 Qv2ray 选项里的配置一致,如 Qv2ray 选项里没有勾选 udp,则这里务必把enable_udp改为 false。
    • 如果希望当本机作为网关设备时为连接到本机的其他设备(如连接到本机开设的 wifi 热点的设备)也提供透明代理,则把enable_gateway改为 true
  • 透明代理的基本原理是拦截系统发出的所有流量,并将这些流量转到代理工具里,从而实现让系统所有流量都走代理的目的。此时,为了避免流量出现死循环(即代理工具发出的流量又转回到代理工具里),需要将代理工具排除在透明代理环境外面。有两种方式可以实现这一点:

    • 通过execsnoop监控代理工具的启动,并自动将其移至透明代理环境外面:

      • cgproxy软件自带execsnoop支持,以上cgproxy测试过的发行版均可支持。
      • 编辑/etc/cgproxy/config.json,在program_noproxy中括号里加上"v2ray""qv2ray",以使qv2ray和v2ray发出的流量不经过透明代理。如果你的v2ray或qv2ray不在PATH里,则需要填写它们的绝对路径。
    • 在每次连接代理节点时,让qv2ray自己把自己移到透明代理环境外面:

      安装 Qvplugin-Command 插件,在插件设置里的“pre-connection”栏里加上一句

      sh -c "cgnoproxy --pid $(pgrep -x qv2ray)"
      
  • 如果启用了 udp 的透明代理(dns 也是 udp),则给 v2ray 二进制文件加上相应的特权:

    sudo setcap "cap_net_admin,cap_net_bind_service=ep" /usr/bin/v2ray
    

    否则 udp 的透明代理可能会出问题。如果每次更新了 v2ray 二进制文件,都需要重新执行此命令。

  • 启动透明代理服务:systemctl start cgproxy.servicesystemctl enable --now cgproxy.service

以上步骤完成后,透明代理应该能正常使用了。

dns

如果勾选了“dns 拦截”,且启用了 dns 和 udp 的透明代理,则 v2ray 会拦截对系统 dns 的请求,并将其转发到 v2ray 的内置 dns 里,即让 v2ray 内置 dns 接管系统 dns。但 v2ray 内置 dns 是会遵循路由规则的。

如果没勾选“dns 拦截”,则 v2ray 虽然不会让内置 dns 接管系统 dns,但如果启用了 dns 和 udp 的透明代理,则系统 dns 也会走透明代理进 v2ray,并遵循 v2ray 的路由规则。

因此,在启用了 dns 和 udp 的透明代理时,若系统 dns 或 v2ray 的内置 dns 配置不当,可能导致 dns 请求发不出去,从而影响正常上网。

由于 qv2ray 常见的路由规则是绕过国内 ip,国外 ip 均走代理。在这个情形中,以下两个配置是典型的有问题的 dns 配置方式:

  • 配置了国外普通 dns 作为首选,但代理本身不支持 udp(此时 dns 查询的 udp 流量出不去,dns 无法查询)
  • 配置了使用域名的 doh 作为首选。此时 doh 的域名无法被解析,从而 doh 也无法使用。

一般而言,如果并不在意将 dns 查询发给谁,那么,在绕过国内 ip 的情况下,只需要配置一个国内普通 dns 作为首选即可保证不会出问题。若代理本身不支持 udp,又希望使用国外 dns,则可以考虑使用使用 ip 的 doh(如https://1.1.1.1/dns-query等)。

如果需要更复杂的 dns 配置,建议参考上游文档,并选择合适的不会影响正常上网的 dns 配置。

Clash

手动下载配置:

wget -O config.yaml [订阅链接]
curl -L -o config.yaml [订阅链接]

测试 clash:

chmod u+x clash_premium
sudo ./clash_premium -d .

设置系统代理:

  • Using GUI:打开 Gnome 系统设置,点击网络代理右边的 ⚙ 按钮,选择手动

    • HTTP 和 HTTPS 代理为 127.0.0.1:7890
    • Socks 主机为 127.0.0.1:7891
  • Using CLI

    gsettings set org.gnome.system.proxy.http host '127.0.0.1'
    gsettings set org.gnome.system.proxy.http port '7890'
    gsettings set org.gnome.system.proxy.https host '127.0.0.1'
    gsettings set org.gnome.system.proxy.https port '7890'
    gsettings set org.gnome.system.proxy.socks host '127.0.0.1'
    gsettings set org.gnome.system.proxy.socks port '7891'
    

    The basic usage of gsettings for reading and writing a particular Dconf setting is as follows.

    # To modify a DConf setting:
    $ gsettings set <schema> <key> <value>
    
    # To read a DConf setting:
    $ gsettings get <schema> <key>
    

相关软件:glider/Lantern/Privoxy/openvpn/Shadowsocks/Tor/trojantrojan教程

clash.service

$ sudo vi clash.service
[Unit]
Description=Clash daemon, A rule-based proxy in Go
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=10
ExecStart=/home/kurome/.opt/clash/clash_premium -d /home/kurome/.opt/clash/

[Install]
WantedBy=multi-user.target

如果不想代理了,可以直接在 clash dashboard 的 Proxy 或者 Settting 里选择 DIRECT,而不是关闭 clash service。

Providers

由于机场的订阅规则并不能完全满足自己的要求,因此自己通常会修改配置文件加上自己的规则。然而当使用机场订阅配置时,自动更新之后会覆盖掉自己配置的规则,又需要重新更改,非常麻烦。

实际上clash在Premium版本中已经提供了proxy-providers的功能,能够完美的解决这个问题。类似的,也有rule-providers的功能,从指定url处获取别人提供的规则,而不用自己来制定。

Premium 版本与普通版本区别是:Premium core is proprietary.

proxy-providers原理是提取指定URL或者指定文件中的proxies字段中的所有内容,即指提取订阅节点的信息,到当前文件中供我们使用。详情看该部分的官方文档。如果订阅链接或文件没有该部分,则会报错:

11:56:42 ERR [Config] configuration file test failed error=initial proxy provider tly error: file must have a `proxies` field path=/home/kurome/.opt/clash/config.yaml

这个时候就要注意看一下自己复制的订阅链接是否是用于 Clash 的,实在没有可以使用订阅转换

proxy-providers的格式为:

proxy-providers:
  provider1: # provider的名称,后期会用到
    type: http
    url: "url" # 机场给你的订阅链接
    interval: 3600 # 每3600秒更新一次订阅
    path: ./provider1.yaml
    health-check:
      enable: true # 是否自动进行latency-test
      interval: 600
      url: http://www.gstatic.com/generate_204
  test:
    type: file
    path: /test.yaml
    health-check:
      enable: true
      interval: 36000
      url: http://www.gstatic.com/generate_204

相关资源:

  • SS-Rule-Snippet:提供clash整体配置模版,有很多清晰注释,方便自定义,推荐使用
  • clash-rules:提供 ruleset, 添加至 rule-providers

Clash Dashboard

使用网页版 clash dashboard 会遇到跨源资源共享错误。可以 clone gh-pages 分支本地使用,直接打开index.html 是依然有错误的,正确的做法是使用 clash 的 external-ui

配置控制界面:在 /path/to/clash/config.yaml 中添加控制界面相关配置

external-controller: 127.0.0.1:9090
external-ui: ./clash-dashboard
secret: "5L2g5aW9Y2xhc2gK"

配置文件

Clash 是基于 Go 语言写的科学上网工具,目前支持 windows, mac, android, openwrt, linux 平台,支持 ss, trojan, vmess, snell 协议,支持分流规则。

clash 配置文件格式为 yaml 格式,格式如下:

port: 7890
socks-port: 7891
allow-lan: true
mode: Rule
log-level: info # silent
external-controller: :9090
proxies:
  - {name: cfmem.com - 🇭🇰 gq - 香港Amazon数据中心 20-1}
proxy-groups:
  - name: 🔰 节点选择
    type: select
    proxies:
      - ♻️ 自动选择
      - 🎯 全球直连
      - cfmem.com - 🇭🇰 gq - 香港Amazon数据中心 20-1
rules:
  - DOMAIN-SUFFIX,local,🎯 全球直连

怎么看呢?当你请求某个网页的时候,就会去匹配 rules,当匹配到某个 rule 后,就看它最后面的 proxy group,proxy group 定义在 proxy-groups 下,其根据不同的类型选择 proxies 中某个 proxy,最后通过该 proxy 打开网页。

proxies

proxies 代表节点数据,所有的分流规则都是按照这些节点数据来的,这里可以有很多个节点数据,可以是 trojan, ss, vmess 类型都可以,我们来看个例子:

{name: cfmem.com - 🇭🇰 gq - 香港Amazon数据中心 20-1, server: xxxx, port: 59113, type: vmess, uuid: 1111111, alterId: 0, cipher: auto, tls: false}

clash 用统一的格式来定义不同的节点类型,用 type 来进行区分,特有的属性只需要在这个结构体加上自己属性就可以, clash 客户端会根据 type 不同而来读数据

proxy-groups

可以把 proxy-groups 理解为一道又道的过滤网,当你发出一个请求时,这个请求将会被在哪一层的过滤网给拦截下来,取决于你的 rules 与 请求匹配。我们来解析一下 proxy-groups 里面的参数。

name

代表组的名称,组的名称可以随意命名,但建议取有意义的名称,组的名称可以被其它的组引用,也可以放在规则里面

type

type 代表这个组的类型,有下面四种情况

  • select 手动选择,该组在节点列表上,手动选择列表或者 proxy-group

  • url-test 延迟最低节点,测试该组所有节点的延迟

  • fallback 回落,连接该组第一个节点,不可用时切换到下一个节点

  • load-balance 负载均衡,由该组2个以上的节点提供链接

proxies

这里可以是组名称或者节点名称,依次从上到下进行选择,比如看下面这个

  - name: 🔰 节点选择
    type: select
    proxies:
      - ♻️ 自动选择
      - 🎯 全球直连
      - cfmem.com - 🇭🇰 gq - 香港Amazon数据中心 20-1
      - cfmem.com - 🇭🇰 gq - 香港Amazon数据中心 26-2
      - cfmem.com - 🇭🇰 gq - 香港Amazon数据中心 28-3
      - cfmem.com - 🇭🇰 香港-4
      - cfmem.com - 🇭🇰 香港 2-5
      - cfmem.com - 🇭🇰 香港 3-6
      - cfmem.com - 🇭🇰 香港 4-7
      - cfmem.com - 🇭🇰 香港 10-8
      - cfmem.com - 🇭🇰 香港 11-9
  - name: ♻️ 自动选择
    type: url-test
    url: http://www.gstatic.com/generate_204
    interval: 300
    proxies:
      - cfmem.com - 🇭🇰 gq - 香港Amazon数据中心 20-1
      - cfmem.com - 🇭🇰 gq - 香港Amazon数据中心 26-2
      - cfmem.com - 🇭🇰 gq - 香港Amazon数据中心 28-3
      - cfmem.com - 🇭🇰 香港-4
      - cfmem.com - 🇭🇰 香港 2-5
      - cfmem.com - 🇭🇰 香港 3-6
      - cfmem.com - 🇭🇰 香港 4-7
      - cfmem.com - 🇭🇰 香港 10-8
      - cfmem.com - 🇭🇰 香港 11-9
      - cfmem.com - 🇭🇰 香港 12-10
  - name: 🌍 国外媒体
    type: select
    proxies:
      - 🔰 节点选择
      - ♻️ 自动选择
      - 🎯 全球直连
      - cfmem.com - 🇭🇰 gq - 香港Amazon数据中心 20-1

名称为自动选择的组会每间隔 300 毫秒去 ping 节点数据,测试的地址是:http://www.gstatic.com/generate_204

而 国外媒体这一项是手动选择默认选择第一个 节点选择,节点选择的第一个是自动选择,所以默认是根据 ping 值来选择节点的

rules

rules 也就是具体的分发规则了,规则一般由 [规则前缀],[域名或地址],[组名] 组成。我们来看下,其中 no-resolve 表示不要解析这条规则,只处理直接 ip 访问请求

rules:
  - DOMAIN-SUFFIX,local,🎯 全球直连
  - IP-CIDR,192.168.0.0/16,🎯 全球直连,no-resolve
  - IP-CIDR,10.0.0.0/8,🎯 全球直连,no-resolve
  - IP-CIDR,172.16.0.0/12,🎯 全球直连,no-resolve
  - IP-CIDR,127.0.0.0/8,🎯 全球直连,no-resolve
  - IP-CIDR,100.64.0.0/10,🎯 全球直连,no-resolve
  - IP-CIDR6,::1/128,🎯 全球直连,no-resolve
  - IP-CIDR6,fc00::/7,🎯 全球直连,no-resolve
  - IP-CIDR6,fe80::/10,🎯 全球直连,no-resolve
  - IP-CIDR6,fd00::/8,🎯 全球直连,no-resolve
  - DOMAIN-KEYWORD,1drv,Ⓜ️ 微软服务

规则前缀有这些内容

  • DOMAIN-SUFFIX 表示包含什么后缀的域名
  • DOMAIN abc.hello.com 表示包含完整的域名
  • DOMAIN-KEYWORD,xxx 表示包含 xxx域名关键字的链接
  • IP-CIDR IPV4匹配
  • SRC-IP-CIDR:源 IP 段匹配
  • GEOIP 数据库(国家代码)匹配GeoIP 是 IP 地理位置数据库,可以根据 IP 地址 (支持 IPv4 和 IPv6), 定位该 IP 所在的地理位置和 ASN 等信息。
  • DST-PORT:目标端口匹配
  • SRC-PORT:源端口匹配
  • PROCESS-NAME 表示进程名称
  • RULE-SET:Rule Provider 规则匹配
  • IP-CIDR6 IPV6匹配
  • MATCH 全匹配(一般放在最后)

DNS污染

DNS服务器即是将用户请求的域名(网站URL)转换为IP地址的服务器。当年中国长城防火墙开始部署时就是通过DNS污染来屏蔽网站的。这项名为DNS污染的技术,就是对用户请求的域名回应一个错误的IP地址,使用户无法访问某个网站。至此,国内几乎所有的公共DNS服务器都被污染,用户无法请求到被屏蔽网站的正确IP地址。但是目前,防火墙的屏蔽功能早已不止DNS污染那么简单了,可以针对IP/域名直接阻断连接,甚至屏蔽了国外未受污染的DNS服务器,因此仅靠国内的DNS是不够翻墙的。

对抗DNS劫持

早期的DNS服务器(我们日常使用的基本也是)都是明文传输数据的,这就意味着防火墙可以探测出你访问的网站,并且直接篡改DNS服务器回应的IP地址。这不仅仅存在于长城防火墙,还存在于某些无良网络运营商,把用户的请求的网站劫持到某个假的网站上。

于是目前出现了DoH与DoT,可使用https/tls 加密传输DNS请求,这使得DNS不再容易被劫持了。国内的许多公共DNS也都提供了这项服务。以下是我所推荐的国内DNS。

  • https://223.5.5.5/dns-query
  • https://223.6.6.6/dns-query
  • https://doh.pub/dns-query

或许可以参考 如何选择适合的公共 DNS?

何时使用

Clash只会在域名匹配为直连时使用配置文件的DNS,其余时刻均交给节点进行远程解析。当然,节点域名也会使用配置文件的DNS。

举个例子,访问 google.com 时,匹配到代理规则,那么这个流量将直接被发送至节点服务器,交给节点处理(通常是节点服务器的DNS解析,这个不用管了)。访问 microsoft.com 时,匹配到直连规则,Clash将使用配置文件的DNS设定进行解析。

DNS配置

首先,打开你的 Clash 配置文件(如果你使用 Clash for Windows 或 Clash for Android, 可以使用软件自带的“覆写/Mixin”功能),添加以下段落:

dns:
  enable: true
  listen: 0.0.0.0:53Copy

这一段的意思是启用 Clash 的 DNS 服务并让其在 53 端口(这是绝大多数操作系统将 DNS 解析报文发送到的端口)监听来自任意网络界面的 DNS 请求。如果你的设备并不需要向其他设备提供解析服务,或你的设备常常需要接入不安全的网络(如手机,笔记本电脑),应当将第三行的 0.0.0.0:53 改为 127.0.0.1:53 让 Clash 仅监听本机的 DNS 解析报文。

(Clash 默认会同时监听 IPv4 和 IPv6 界面,如果你不需要后者,可以添加一行 ipv6: false

由于连接到加密 DNS 服务时,需要解析服务器本身的域名,因此需要指定一些相对干净的国内 明文 DNS 服务器地址。继续添加以下部分(注意缩进):

#--omitted--
default-nameserver:
   - 119.29.29.29
   - 223.5.5.5Copy

当收到 DNS 解析请求时,Clash 会使用以上 DNS 服务器解析加密 DNS 服务器地址并建立连接。

接下来,指定解析国内域名时使用的加密 DNS 服务器地址:

#--omitted--
nameserver:
   - https://doh.pub/dns-query
   - https://dns.alidns.com/dns-queryCopy

Clash 支持 DoH(https://domain.tld/dns-query 形式) 和 DoT(tls://domain.tld 形式)两种加密 DNS 协议,不支持 DoQ.(当然也支持在此指定备用的明文 DNS)

然后,指定解析国外域名时使用的加密 DNS 服务器地址,并设置分流规则:

#--omitted--
fallback:
   - https://1.1.1.1/dns-query
   - https://dns.google/dns-query
fallback-filter:
   geoip: true
   geoip-code: CN
   ipcidr:
     - 240.0.0.0/4Copy

“fallback” 字段指定的 DNS 服务器将被用于解析非国外域名,而 “fallback-filter” 字段则实现我们想要的分流规则——当请求解析的域名在 GeoIP 数据库内的国家代码不是 CN 时,或是域名在前文设置的 DNS 服务器内的解析结果位于 240.0.0.0/4 这一 IP 段内时(被屏蔽的域名解析常常会被污染到这一段),使用 “fallback” 字段指定的 DNS 服务器解析域名。

最后,修改系统 DNS 服务器为 127.0.0.1 即可。

代理环境中的 DNS 解析行为

虽然 Fake IP 这个概念早在 2001 年就被提出来了,但是到 Clash 提供 fake-ip 增强模式以后,依然有很多人对 Fake IP 这个概念以及其作用知之甚少。本文就简单谈谈在代理环境中,TCP 连接建立之前发生的事。由于移动设备操作系统中网络栈相对复杂,本文的例子也并不一定适用于移动端环境。文章中也许会存在很多错误,也希望各路大佬的勘误和斧正。

不使用代理

如果在不使用任何代理的情况下,打开一个没有命中 DNS 缓存的网站(比如 blog.skk.moe)的时候,浏览器和操作系统大概会执行这么一些操作:

  1. 浏览器自己都有 DNS 缓存机制,因此浏览器会先开始寻找自己的缓存,不过没有找到 blog.skk.moe 的解析结果
  2. 浏览器通过调用操作系统的 getaddrinfo 方法,向操作系统寻求解析结果
  3. 操作系统自己也有一层 DNS 缓存,但是现在操作系统从自己的缓存中依然找不到这一结果
  4. 在系统的网络设置之中有设置上游 DNS 地址,假设操作系统中设置的是 119.29.29.29,那么操作系统会向 119.29.29.29 发起解析请求(UDP 流量)拿到 blog.skk.moe 的 IP
  5. 当然如果 119.29.29.29 自己没有 blog.skk.moe 的解析结果会找它的上游去要。不过我们不关心这一点,反正最后 119.29.29.29 会把 blog.skk.moe 的解析结果返回给设备的操作系统
  6. 现在,浏览器已经可以开始向 blog.skk.moe 的 IP 发起 HTTPS 连接了

以上是打开一个网页常见的 DNS 解析流程,对于其它非 HTTP 的 TCP 连接(比如 SMTP)也都差不多是这个流程——由于 TCP/IP 的协议特性,在应用发起 TCP 连接时,会先发出一个 DNS question(发一个 IP Packet),获取要连接的服务器的 IP 地址,然后直接向这个 IP 地址发起连接。

设置代理并使用直连

现在,我们在应用程序(比如我们的浏览器、或者其它应用)中设置了代理,但是这个代理不涉及到任何远端服务器(直连模式)。接下来以设置了 SOCKS5 代理的浏览器为例。

  1. 浏览器不再需要从自己的 DNS 缓存中寻找 blog.skk.moe,因为已经有了 SOCKS5 代理,浏览器可以直接将域名封装在 SOCKS5 流量之中发往代理客户端
  2. 代理客户端从 SOCKS5 流量中抽出 blog.skk.moe 这个域名并设法获得解析结果
  3. 代理客户端将你的 SOCKS5 流量还原成标准的 TCP 请求
  4. 代理客户端将这个 TCP 连接建立起来,在这个例子之中 TCP 连接承载的是 HTTPS

之前由于获取解析结果是浏览器在操作,而大部分浏览器都会选择调用系统的 getaddrinfo 方法,因此如果你想要在 DNS 上做一些黑魔法就只能在操作系统层面实现,比如在本机或者别处架设一个带黑魔法的 DNS 服务器,然后你系统中设置使用这个 DNS 服务器。现在 DNS 解析是由代理客户端执行,因此在代理客户端上就可以实现一些黑魔法。比如 Surge 自己实现了一个 DNS Server 可以并发向多个上游同时发起查询、比如 V2Ray 可以实现不同域名的查询分流,等等。当然代理客户端也可以使用操作系统的 getaddrinfo 方法。

设置代理并将流量转发到远端服务器

现在在上一步的基础之上,我们为代理服务器设置了一个远端服务器,这个代理会使用 某种协议 和远端服务器通信,并且这种协议和 SOCKS5 一样支持将域名封装在传输中。浏览器和代理客户端之间依然使用 SOCKS5 通信。

  1. 因为已经有了 SOCKS5 代理,浏览器可以直接将域名 blog.skk.moe 和整个请求封装在 SOCKS5 流量之中发往代理客户端
  2. 代理客户端从 SOCKS5 流量中抽出 blog.skk.moe 这个域名以及其它数据
  3. 代理客户端使用 某种协议 将浏览器发出的 SOCKS5 的流量重组并发给远端服务器
  4. 远端服务器使用相同的 某种协议 从流量中获得其中的域名 blog.skk.moe
  5. 远端服务器的代理服务端发起了一次 DNS 解析请求试图解析 blog.skk.moe。绝大部分情况下,代理的服务端都会直接使用操作系统的 getaddrinfo 方法、也就是由远端服务器的操作系统负责 DNS

这一次,不论是代理客户端还是你的浏览器都没有进行 DNS 解析,DNS 解析是在远端服务器上进行的。因为 某种协议 支持封装域名,然后这一次和 blog.skk.moe 连接的是远端服务器,考虑到针对 CDN 优化,DNS 解析自然需要在远端服务器上执行。

现在我已经介绍了通过代理直连和通过代理发送给远端服务器了。但是毫无疑问,我相信本文所有的读者自己使用的上网方式都不会是全面直连或者全面代理。这就是接下来要讲的:

设置代理并使用 IP 规则和域名规则进行分流

分流是一个麻烦事。一般情况下,你可能会需要使用域名进行分流(不论是白名单还是黑名单)。不过更多情况下你会使用到基于 IP 的规则来进行分流。

先来看第一个例子:使用域名规则进行分流。

  1. 浏览器将带有域名 blog.skk.moe 的 HTTPS 请求封装在 SOCKS5 流量之中发往代理客户端
  2. 代理客户端从 SOCKS5 流量中抽取出域名 blog.skk.moe
  3. 代理客户端开始将blog.skk.moe 和域名规则列表开始比较。这个列表可以是白名单或黑名单,域名可能也没有匹配上。反正最终比较得出的结果就是 blog.skk.moe 是否需要走代理。
  4. 如果不需要走代理,代理客户端剩下会做的事情和本文第二部分「设置代理并使用直连」就完全一样了;同理,需要走代理的话就需要进行本文第三部分的那个流程

使用域名规则分流很简单,除非 blog.skk.moe 最终是直连,否则代理客户端不需要进行 DNS 解析。

现在来看第二个例子:使用 IP 规则分流。

  1. 浏览器将带有域名 blog.skk.moe 的 HTTPS 请求封装在 SOCKS5 流量之中发往代理客户端
  2. 代理客户端从 SOCKS5 流量中抽取出域名 blog.skk.moe
  3. 代理客户端得到 blog.skk.moe 的解析结果
  4. 代理客户端开始将blog.skk.moe 的解析结果和 IP 规则列表开始比较。这个列表可以是 cnlist 或者 MaxMind IP 数据库。反正最终得出的结果就是 blog.skk.moe 解析结果的 IP 是否需要走代理。
  5. 如果不需要走代理,代理客户端剩下会做的事情和本文第二部分「设置代理并使用直连」就完全一样了;同理,需要走代理的话就需要进行本文第三部分的那个流程。

使用 IP 规则分流,前提首先你得有一个 IP 拿来比较。所以代理客户端必须先进行一次 DNS 解析。使用什么方法进行 DNS 解析并不重要,之前已经说过代理客户端甚至可以使用自己的黑魔法,而我们只需要关心最终代理客户端拿到了一个 IP 并且可以用于规则判定。

此时需要注意的是,虽然代理客户端获得了一个 IP,但是你只有在直连的时候,代理客户端可能(并且基本上都会)复用这个 IP;如果是将流量交给远程服务器,由于 某种协议 支持封装域名,因此远程服务器拿到的还是域名不是 IP、还需要进行一次解析。也就是说,远端服务器连接的 IP 与 代理客户端解析得到的 IP 毫无关系。

使用 redir / tun2socks 实现全局流量经过代理

在开始之前,我们先复习一下 TCP/IP 协议怎么说的——「在应用发起 TCP 连接时,会先发出一个 DNS question(发一个 IP Packet),获取要连接的服务器的 IP 地址,然后直接向这个 IP 地址发起连接」

全局流量代理可能会出现在路由器上或者 TUN/TAP 型的支持全局代理客户端上。用户不再主动为每个应用程序设置代理。此时应用程序是不会感知到代理客户端的存在,它们会正常的发起 TCP 连接,并且由于 TCP/IP 协议,在拿到 DNS 解析结果之前,连接是不能建立的。

  1. 浏览器自己都有 DNS 缓存机制,因此浏览器会先开始寻找自己的缓存,不过没有找到 blog.skk.moe 的解析结果
  2. 浏览器通过调用操作系统的 getaddrinfo 方法,向操作系统寻求解析结果
  3. 操作系统自己也有一层 DNS 缓存,但是现在操作系统从自己的缓存中依然找不到这一结果
  4. 在系统的网络设置之中有设置上游 DNS 地址。代理客户端可能会修改系统设置中的 DNS 到 127.0.0.1 或者别的 IP、也可能保留用户之前的设置,这无所谓,因为…
  5. 操作系统发出的 DNS 解析请求会经过代理客户端并最终被截获
  6. 代理客户端可以将这个解析请求原样发出去、或者用自己的黑魔法,总之代理客户端都会拿到一个解析结果
  7. 代理客户端将这个解析结果返回回去,操作系统拿到了这个解析结果并返回给浏览器
  8. 浏览器对这个解析结果的 IP 建立一个 TCP 连接并发送出去
  9. 这个 TCP 连接被代理客户端截获。由于之前代理客户端进行的 DNS 解析请求这一动作,代理客户端可以找到这个只包含目标 IP 的 TCP 连接原来的目标域名
  10. 如果是支持 redir 的代理客户端,那么代理客户端就会直接将域名和 TCP 连接中的其它数据封装成 某种协议 发给远端服务器;或者封装成 SOCKS5 后交给支持 SOCKS5 的代理客户端

如果代理客户端需要按照域名进行分流,一般会在第 6 步代理客户端解析出一个 IP 或者第 9 步代理客户端拿到域名以后。FancySS、KoolSS、SSTap 的流程大抵都是如此。

和应用程序直接将流量封装成 SOCKS5 大有不同,在类似于透明代理的环境下浏览器和其它应用程序是正常地发起 TCP 连接。因此除非得到一个 DNS 解析结果,否则 TCP 连接不会建立;代理客户端也会需要通过这个 DNS 查询动作,才能找到之后的 TCP 连接的域名。 你大概能够发现,浏览器、应用程序直接设置 SOCKS5 代理的话,可以不在代理客户端发起 DNS 解析请求就能将流量发送给远端服务器;而在透明代理模式下,不论是否需要 IP 规则分流都需要先进行一次 DNS 解析才能建立连接。

有没有办法能像直接设置 SOCKS5 代理一样省掉一次 DNS 解析呢?有,就是代理客户端自己不先执行查询动作,丢一个 Fake IP 回去让浏览器、应用程序立刻建立 TCP 连接:

在 redir / tun2socks 中使用 Fake IP

Fake IP 的定义出自 RFC3089。这个 RFC 定义了一种新的将 TCP 连接封装成 SOCKS 协议的方法。

  1. 浏览器自己都有 DNS 缓存机制,因此浏览器会先开始寻找自己的缓存,不过并没有找到 blog.skk.moe 的解析结果
  2. 浏览器通过调用操作系统的 getaddrinfo 方法,向操作系统寻求解析结果
  3. 操作系统自己也有一层 DNS 缓存,但是现在操作系统从自己的缓存中依然找不到这一结果
  4. 在系统的网络设置之中设置了一个专门的上游 DNS 地址,可能是用户手动设置的也可能是代理客户端设置的。不论如何,这个设置最终会使操作系统向代理客户端发起 DNS 请求
  5. 操作系统发出的 DNS 解析请求会经过代理客户端并最终被截获
  6. 代理客户端从解析请求中获得域名,从 Fake IP 池中选取一个 IP 建立映射
  7. 代理客户端将这个 Fake IP 返回回去,操作系统拿到了这个 Fake IP 并返回给浏览器
  8. 浏览器对 Fake IP 建立一个 TCP 连接并发送出去
  9. 这个 TCP 连接被代理客户端截获。代理客户端抽取出 Fake IP 并反查出这个 TCP 连接中对应的域名
  10. 有了 TCP 连接和域名,代理客户端可以轻易地将其使用 SOSCKS5 或者 某种协议 进行封装

有了 Fake IP,代理客户端无需进行 DNS 解析。最后不论是浏览器、代理客户端还是远端服务器都不会去和 Fake IP 进行连接,因为在代理客户端这里就已经完成了截获、重新封装。

即使按照域名规则分流,代理客户端都没有进行 DNS 解析的需要。只有在遇到了按照 IP 进行分流的规则时,代理客户端才需要进行一次解析拿到一个 IP 用于判断。即便如此,这个 IP 只用于分流规则的匹配,不会被用于实际的连接。

FancySS 和 Surge / Clash 的区别

FancySS 是使用的 redir,Surge 的增强模式使用的是 Fake IP,Clash 的增强模式既有 redir-host 也有 Fake IP。首先把 FancySS 等路由器上常见的代理客户端和 Clash 的 redir-host 分为一类,Surge 的增强模式和 Clash 的 fake-ip 模式分为另一类。

路由器上常见的代理客户端一般内置了 dns2socks、dnscryp-proxy、PCap_DNSProxy 等等 DNS 方案、也支持按照一定的规则进行分流,但是都是用于答复应用程序的 DNS question 使其建立 TCP 连接的,除非直连,否则通过这些 DNS 方案拿到的解析结果的 IP 并不会被用上。 大部分路由器上的代理客户端,DNS 解析请求都是通过路由器本机发出(或转发到单一远端服务器进行解析),因此解析结果只能说「至少能用」(不一定是有 CDN 优化的,甚至有可能会有 DNS 污染),如果流量不经过代理客户端直接发往这些 IP 地址,一般也不会影响浏览器、应用程序的正常使用。因此路由器上的代理客户端可以实现通过 iptables 控制让某些端口、某些设备的流量不经过代理客户端。 而在 Fake IP 模式下,浏览器、应用程序都是对 Fake IP 发起连接,如果没有代理客户端对连接进行重新封转,那么这部分流量就不能被发往真实的目的 IP,因此所有流量都必须经过代理客户端,而根据端口、设备的分流就需要由代理客户端自己实现。

如果操作系统或者浏览器缓存了 DNS 解析结果

之前的透明代理的两个例子中,我们都假定浏览器和操作系统都没有缓存 DNS 解析结果。但是,如果操作系统或者应用程序缓存了 DNS 解析结果会发生什么?

如果是不使用 Fake IP 的 redir / tun2socks 情况下,由于操作系统、浏览器或者应用程序中的任何一个缓存了 DNS 解析结果,因此 TCP 连接可以直接根据缓存的解析结果的 IP 建立,代理客户端并没有预先收到对应的 DNS question。在这种情况下,代理客户端有可能直接将这个连接视为和 IP 连接而不是和域名连接,根据域名规则的分流可能就会因此失效,不过根据 IP 分流的规则没有失效。 如果为了避免域名分流规则失效,你可以设法阻止操作系统或者浏览器缓存 DNS 解析结果,这样每次建立 TCP 连接之前都会发送 DNS question 使代理客户端探测到域名。但是这意味着每次 TCP 连接建立都需要代理客户端进行一次 DNS 解析请求(当然代理客户端可以对 DNS 解析进行缓存避免出现延时激增)。

而对于 Fake IP 模式来说,由于代理客户端内存储有 Fake IP 和真实域名之间的映射表,因此即使操作系统或应用程序缓存了 Fake IP,在之后的 TCP 连接中,代理客户端收到流量后依然可以抽取出 Fake IP 反查出域名,因此不受 DNS 缓存的影响。

我在这里留几个问题给大家思考一下:

  • 如果使用了 Fake IP,代理客户端不论域名是否真实存在都会返回一个 Fake IP 给浏览器,那么浏览器在试图访问一个不存在的域名时,错误信息应该是什么样的?会不会出现 DNS 解析失败的错误信息?
  • 如果操作系统或者浏览器缓存了 Fake IP,但是代理客户端中 Fake IP 和域名的映射表丢失以后,会出现什么状况?可能会出现什么错误信息?

第二个问题很有趣。因为如果你找到了第二个问题的答案,你就会意识到 Clash 在 Fake IP 模式下偶发的无法上网的原因了。

参考资料

CFW TUN 模式

“系统代理”一般只是桌面环境下的约定,需要 app 遵循约定才行。也就是说 HTTP_PROXY 这种环境变量只是约定俗成的,大家都从这里面读取代理地址,但是程序里必须要有读取这个变量的相关代码才行。

因此某些软件&命令行软件不支持系统代理。

tun 模式对全部 app 生效——对于不遵循系统代理的软件,TUN 模式可以接管其流量并交由 CFW 处理。启动 TUN 模式需要进行如下操作:

  1. 安装 nftables 和 iproute2 并重启

    sudo apt install nftables iproute2
    sudo reboot
    
  2. 点击GeneralService Mode右边Manage,在打开窗口中安装服务模式,安装完成应用会自动重启(某些系统需要手动重启 APP),Service Mode 右边地球图标变为绿色即安装成功

  3. 点击GeneralTUN Mode右边开关启动 TUN 模式

  4. 无法安装参考

    curl https://gist.githubusercontent.com/Fndroid/2119fcb5ccb5a543a8f6a609418ae43f/raw/592eba4f480c7ccb4f29c9b8e80d24bfd5dda8cf/linux.sh > cfw-tun.sh && chmod +x cfw-tun.sh && sudo ./cfw-tun.sh install <cfw安装目录>
    

    如要卸载则将 install 改为 uninstall,最后一部分位 CFW 安装目录

TProxy

TProxy 含义:

  • 透明代理:在正向代理中,一个软件如果想走 client 的代理服务,我们必须显式配置该软件,对该软件来说,有没有走代理是很明确的,大家都“心知肚明”。而透明代理则与正向代理相反,当我们设置好合适的防火墙规则(仅以 Linux 的 iptables 为例),我们将不再需要显式配置这些软件来让其经过代理或者不经过代理(直连),因为这些软件发出的流量会自动被 iptables 规则所处理,那些我们认为需要代理的流量,会被通过合适的方法发送到 client 进程,而那些我们不需要代理的流量,则直接放行(直连)。这个过程对于我们使用的软件来说是完全透明的,软件自身对其一无所知。这就叫做 透明代理。注意,所谓透明是对我们使用的软件透明,而非对 client、server 或目标网站透明,理解这一点非常重要。
  • 内核模块:内核里支持上面描述的透明代理的模块,TProxy 模块工作在 mangle 表上。

Summary

执行下面的命令开启透明代理。由于使用了 TPROXY 方式的透明代理,所以 TCP 流量也是使用 mangle 表。以下命令中,以 # 开头的为注释。

# 设置策略路由
ip rule add fwmark 1 table 100 
ip route add local 0.0.0.0/0 dev lo table 100

# 代理局域网设备
iptables -t mangle -N V2RAY
iptables -t mangle -A V2RAY -d 127.0.0.1/32 -j RETURN
iptables -t mangle -A V2RAY -d 224.0.0.0/4 -j RETURN 
iptables -t mangle -A V2RAY -d 255.255.255.255/32 -j RETURN 
iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p tcp -j RETURN # 直连局域网,避免 V2Ray 无法启动时无法连网关的 SSH,如果你配置的是其他网段(如 10.x.x.x 等),则修改成自己的
iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN # 直连局域网,53 端口除外(因为要使用 V2Ray 的 DNS)
iptables -t mangle -A V2RAY -m mark --mark 0xff -j RETURN    # 直连 SO_MARK 为 0xff 的流量(0xff 是 16 进制数,数值上等同与上面V2Ray 配置的 255),此规则目的是解决v2ray占用大量CPU(https://github.com/v2ray/v2ray-core/issues/2621)
iptables -t mangle -A V2RAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 # 给 UDP 打标记 1,转发至 12345 端口
iptables -t mangle -A V2RAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 # 给 TCP 打标记 1,转发至 12345 端口
iptables -t mangle -A PREROUTING -j V2RAY # 应用规则

# 代理网关本机
iptables -t mangle -N V2RAY_MASK 
iptables -t mangle -A V2RAY_MASK -d 224.0.0.0/4 -j RETURN 
iptables -t mangle -A V2RAY_MASK -d 255.255.255.255/32 -j RETURN 
iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p tcp -j RETURN # 直连局域网
iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN # 直连局域网,53 端口除外(因为要使用 V2Ray 的 DNS)
iptables -t mangle -A V2RAY_MASK -m mark --mark 0xff -j RETURN    # 直连 SO_MARK 为 0xff 的流量(0xff 是 16 进制数,数值上等同与上面V2Ray 配置的 255),此规则目的是避免代理本机(网关)流量出现回环问题
iptables -t mangle -A V2RAY_MASK -p udp -j MARK --set-mark 1   # 给 UDP 打标记,重路由
iptables -t mangle -A V2RAY_MASK -p tcp -j MARK --set-mark 1   # 给 TCP 打标记,重路由
iptables -t mangle -A OUTPUT -j V2RAY_MASK # 应用规则

# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升
iptables -t mangle -N DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT

执行了以上 ip 和 iptables 命令后,局域网同网段的设备以及网关本身就可以直接翻墙了。

OUTPUT&PREROUTING

从本机出去的数据包会经过 OUTPUT 链,而从外部发往本机的数据包会经过 PREROUTING 链(当然也会经过 INPUT 链,但因为 tproxy 只能工作在 PREROUTING 链,所以我们只关心 PREOUTING 链)。

由于 tproxy 只能工作在 PREROUTING 链,从本机发出去的数据包会直接通过 OUTPUT 链出去了,本机数据包没有机会走一下 PREROUTING 链。为了让本机数据经过 PREROUTING,我们可以用的路由表解决。执行如下命令:

# 设置策略路由
ip rule add fwmark 1 table 100 
ip route add local 0.0.0.0/0 dev lo table 100

第一行添加一条 ip 规则,表示被标记为 1 的的数据包的走向要查表 100 。 第二行声明所有的 IPv4 地址在表 100 中均为 local(IP 数据包的目标IP与来源IP都为本机IP),大致是说对于表 100 的流量,都要发到本机(也就是说从 OUTPUT 链出去的包要回到 PREROUTING 链,原本 PREROUTING => FORWARD 的包改为 PREROUTING => INPUT => Local Process)。

我们来观察这张图。只要 OUTPUT 的最后我们的目标恰好是本机的话,那么这份数据报就会重新回到 iptables 的手中,也就和局域网的其他机器所发送的报文一样了。(clash/v2ray 都是通过域名而非 ip 进行代理的,所以IP 数据包的目标IP与来源IP随便改)

在 OUTPUT 链上打标记命令如下:

iptables -t mangle -A OUTPUT -p tcp -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -p udp -j MARK --set-mark 1

使用 Chain

上面的规则虽然完成了重回 PREROUTING 的能力,但有些数据包应当直接从 OUTPUT 链出去,比如访问网关管理页面(192.168.22.1),或者是 NAS 的 192.168.22.2。所以我们需要跳过一部分的数据包避免标记上 1。

iptables -t mangle -A OUTPUT -d 192.168.0.0/16 -j RETURN

这一条命令要在前面的 -j MARK 命令之前执行,匹配规则会根据创建的规则顺序按顺序执行。

此时我们将编写 iptables 规则类比一下: 写 iptables 规则,就像写代码,OUTPUT 等链是程序内置的函数,它会在对应时机调用,我们需要做是填充这个函数的逻辑。所以,链 = 函数。这就清晰很多了。 iptables 还给我们提供了创建自定义链(函数)的能力,有了自定义链(函数)我们可以更好地管理规则。

对于上面的 OUTPUT 管理,我们可以改写成:

iptables -t mangle -N V2RAY_MASK 
iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p tcp -j RETURN
iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p udp -j RETURN
iptables -t mangle -A V2RAY_MASK -p udp -j MARK --set-mark 1
iptables -t mangle -A V2RAY_MASK -p tcp -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -j V2RAY_MASK

应用 tproxy

有了以上的内容,我们可以开始把数据发的 tproxy,tproxy 翻译过来就是内核提供的透明代理能力。假定我们设置的 tproxy 端口为 12345,如下命令可以将数据包通过 tproxy 发给代理client:

iptables -t mangle -A PREROUTING -p tcp -j TPROXY --on-port --tproxy-mark 1
iptables -t mangle -A PREROUTING -p udp -j TPROXY --on-port --tproxy-mark 1

因为这里TProxy 的目标地址不是本机。也就是说,如果不设置 mark,那么这份报文就会被转发(被 FORWARD 链处理)而不是被 INPUT 链处理。为了实现透明代理,这份报文必须被本机处理,因此 TProxy 就必须设置 --tproxy-mask,结合上文理解。

然后创建自定义的链,上面的两行命令 PREROUTING 在增加更多的规则后会很难管理:

iptables -t mangle -N V2RAY
iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p tcp -j RETURN
iptables -t mangle -A V2RAY -p udp -j TPROXY --on-port 12345 --tproxy-mark 1
iptables -t mangle -A V2RAY -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1
iptables -t mangle -A PREROUTING -j V2RAY

解决回环问题

这里产生了一个回环:

  • 本机发出来去往外网的数据包通过 mark 回到 PREROUTING
  • 通过 tproxy 进入代理client
  • 本机代理client发出来去往外网的数据包通过 mark 回到 PREROUTING
  • 通过 tproxy 进入代理client
  • 本机代理client发出来去往外网的数据包通过 mark 回到 PREROUTING
  • …..

我们需要解决掉,即让本机代理client发出来的数据包直接从 OUTPUT 链出去。

mark 规避

一种方式是对出站流量再打一个 mark,通过设置 iptables 规则对对应 mark 的流量直连,来规避代理client流量,防止回环。

首先要在代理client的配置中给其包加一个 255 的 mark,这个 mark 与下文 iptables 命令配合,以直连代理client发出的 SO_MARK 为 0xff 的流量 (0xff 是 16 进制数,数值上等同与配置的 255)

# OUTPUT
# 此规则目的是避免代理本机(网关)流量出现回环问题
iptables -t mangle -A V2RAY_MASK -m mark --mark 0xff -j RETURN

这么做有以下几个问题:

  1. 莫名流量进入 PREROUTING 链,解决如下

    # PREROUTING
    # 此规则目的是解决v2ray占用大量CPU
    iptables -t mangle -A V2RAY -m mark --mark 0xff -j RETURN
    
  2. 安卓系统有自己的 mark 机制,该方案在安卓上不可用

gid/uid 规避

思路:

  • tproxy 流量只能被 root 权限用户(uid==0)或其他有 CAP_NET_ADMIN 权限的用户接收。
  • iptables 规则可以通过 uid(用户 id)和 gid(用户组 id)分流。
  • 让代理client运行在一个 uid==0 但 gid!=0 的用户上,设置 iptables 规则不代理该 gid 的流量来规避 代理client流量。

使用以下命令可以创建一个名为 clash,uid 为 0,gid 为 23333 的用户,用户名和 gid 可以自己定,uid 必须为 0。

# grep -qw clash /etc/passwd || echo "clash❌0:23333:::" >> /etc/passwd

使用如下命令可以验证创建的用户是否正常:

sudo -u clash id

接下来我们使用这个用户启动 clash:

sudo -u clash /usr/local/bin/clash -d /etc/clash

iptables 执行在 OUTPUT 链改为如下命令:

# OUTPUT
iptables -t mangle -A V2RAY_MASK -m owner --gid-owner 23333 -j RETURN

劫持 DNS

使用 tproxy 能力时,需要让代理client接管 DNS 流量,有两种方式:

  • 停掉本地的 DNS 服务,将代理client的 DNS 服务端口改为 53

    # PREROUTING
    iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
    
    # OUTPUT
    iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
    
  • 将 DNS 查询数据包转发到代理client

    # PREROUTING
    iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
    iptables -t nat -A V2RAY -p udp --dport 53 -j REDIRECT --to-ports 10053
    
    # OUTPUT
    iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
    iptables -t nat -A V2RAY_MASK -p udp --dport 53 -j REDIRECT --to-ports 10053
    

    10053 是在代理client上设置的 DNS 服务端口。

WireGuard

官方文档:https://github.com/pirate/wireguard-docs

WireGuard 是由 Jason Donenfeld 等人用 C 语言编写的一个开源 VPN 协议,被视为下一代 VPN 协议,旨在解决许多困扰 IPSec/IKEv2OpenVPNL2TP 等其他 VPN 协议的问题。它与 TincMeshBird 等现代 VPN 产品有一些相似之处,即加密技术先进、配置简单。从 2020 年 1 月开始,它已经并入了 Linux 内核的 5.6 版本,这意味着大多数 Linux 发行版的用户将拥有一个开箱即用的 WireGuard。

术语

Peer/Node/Device

连接到 VPN 并为自己注册一个 VPN 子网地址(如 192.0.2.3)的主机。还可以通过使用逗号分隔的 CIDR 指定子网范围,为其自身地址以外的 IP 地址选择路由。

中继服务器(Bounce Server)

一个公网可达的对等节点,可以将流量中继到 NAT 后面的其他对等节点。Bounce Server 并不是特殊的节点,它和其他对等节点一样,唯一的区别是它有公网 IP,并且开启了内核级别的 IP 转发,可以将 VPN 的流量转发到其他客户端。

子网(Subnet)

一组私有 IP,例如 192.0.2.1-255192.168.1.1/24,一般在 NAT 后面,例如办公室局域网或家庭网络。

CIDR 表示法

CIDR中文全称是无分类域间路由选择,英文全称是Classless Inter-Domain Routing,在平常,大家多称之为无分类编址,它也是构成超网的一种技术实现。CIDR在一定程度上解决了路由表项目过多过大的问题。CIDR之所以称为无分类编址,就是因为CIDR完全放弃了之前的分类IP地址表示法,它真正消除了传统的A类、B类、C类地址以及划分子网的概念,它使用如下的IP地址表示法:

IP地址 ::= {<网络前缀>, <主机号>} / 网络前缀所占位数

CIDR仅将IP地址划分为网络前缀和主机号两个部分,可以说又回到了二级IP地址的表示,不过大家要注意,最后面用“/”斜线分隔,在其后写上了网络前缀所占的位数,这样就不需要告知路由器地址掩码,仅需要通过网络前缀所占的位数就可以得到地址掩码,为了统一,CIDR中的地址掩码依然称为子网掩码。

NAT

子网的私有 IP 地址由路由器提供,通过公网无法直接访问私有子网设备,需要通过 NAT 做网络地址转换。路由器会跟踪发出的连接,并将响应转发到正确的内部 IP。

公开端点(Public Endpoint)

节点的公网 IP 地址:端口,例如 123.124.125.126:1234,或者直接使用域名 some.domain.tld:1234。如果对等节点不在同一子网中,那么节点的公开端点必须使用公网 IP 地址。

私钥(Private key)

单个节点的 WireGuard 私钥,生成方法是:wg genkey > example.key

公钥(Public key)

单个节点的 WireGuard 公钥,生成方式为:wg pubkey < example.key > example.key.pub

DNS

域名服务器,用于将域名解析为 VPN 客户端的 IP,不让 DNS请求泄漏到 VPN 之外。

工作原理

中继服务器工作原理

中继服务器(Bounce Server)和普通的对等节点一样,它能够在 NAT 后面的 VPN 客户端之间充当中继服务器,可以将收到的任何 VPN 子网流量转发到正确的对等节点。事实上 WireGuard 并不关心流量是如何转发的,这个由系统内核和 iptables 规则处理。

如果所有的对等节点都是公网可达的,则不需要考虑中继服务器,只有当有对等节点位于 NAT 后面时才需要考虑。

*在 WireGuard 里,客户端和服务端基本是平等的,差别只是谁主动连接谁而已。*双方都会监听一个 UDP 端口,谁主动连接,谁就是客户端。主动连接的客户端需要指定对端的公网地址和端口,被动连接的服务端不需要指定其他对等节点的地址和端口。如果客户端和服务端都位于 NAT 后面,需要加一个中继服务器,客户端和服务端都指定中继服务器作为对等节点,它们的通信流量会先进入中继服务器,然后再转发到对端。

WireGuard 是支持漫游的,也就是说,双方不管谁的地址变动了,WireGuard 在看到对方从新地址说话的时候,就会记住它的新地址(跟 mosh 一样,不过是双向的)。所以双方要是一直保持在线,并且通信足够频繁的话(比如配置 persistent-keepalive),两边的 IP 都不固定也不影响的。

流量路由

利用 WireGuard 可以组建非常复杂的网络拓扑,这里主要介绍几个典型的拓扑:

  1. 端到端直接连接

这是最简单的拓扑,所有的节点要么在同一个局域网,要么直接通过公网访问,这样 WireGuard 可以直接连接到对端,不需要中继跳转。

  1. 一端位于 NAT 后面,另一端直接通过公网暴露

这种情况下,最简单的方案是:通过公网暴露的一端作为服务端,另一端指定服务端的公网地址和端口,然后通过 persistent-keepalive 选项维持长连接,让 NAT 记得对应的映射关系。

  1. 两端都位于 NAT 后面,通过中继服务器连接

大多数情况下,当通信双方都在 NAT 后面的时候,NAT 会做源端口随机化处理,直接连接可能比较困难。可以加一个中继服务器,通信双方都将中继服务器作为对端,然后维持长连接,流量就会通过中继服务器进行转发。

  1. 两端都位于 NAT 后面,通过 UDP NAT 打洞

上面也提到了,当通信双方都在 NAT 后面的时候,直接连接不太现实,因为大多数 NAT 路由器对源端口的随机化相当严格,不可能提前为双方协调一个固定开放的端口。必须使用一个信令服务器(STUN),它会在中间沟通分配给对方哪些随机源端口。通信双方都会和公共信令服务器进行初始连接,然后它记录下随机的源端口,并将其返回给客户端。这其实就是现代 P2P 网络中 WebRTC 的工作原理。有时候,即使有了信令服务器和两端已知的源端口,也无法直接连接,因为 NAT 路由器严格规定只接受来自原始目的地址(信令服务器)的流量,会要求新开一个随机源端口来接受来自其他 IP 的流量(比如其他客户端试图使用原来的通信源端口)。运营商级别的 NAT 就是这么干的,比如蜂窝网络和一些企业网络,它们专门用这种方法来防止打洞连接。更多细节请参考下一部分的 NAT 到 NAT 连接实践的章节。

如果某一端同时连接了多个对端,当它想访问某个 IP 时,如果有具体的路由可用,则优先使用具体的路由,否则就会将流量转发到中继服务器,然后中继服务器再根据系统路由表进行转发。你可以通过测量 ping 的时间来计算每一跳的长度,并通过检查对端的输出(wg show wg0)来找到 WireGuard 对一个给定地址的路由方式。

报文格式

WireGuard 使用加密的 UDP 报文来封装所有的数据,UDP 不保证数据包一定能送达,也不保证按顺序到达,但隧道内的 TCP 连接可以保证数据有效交付。WireGuard 的报文格式如下图所示:

img

性能

WireGuard 声称其性能比大多数 VPN 协议更好,但这个事情有很多争议,比如某些加密方式支持硬件层面的加速。

WireGuard 直接在内核层面处理路由,直接使用系统内核的加密模块来加密数据,和 Linux 原本内置的密码子系统共存,原有的子系统能通过 API 使用 WireGuard 的 Zinc 密码库。WireGuard 使用 UDP 协议传输数据,在不使用的情况下默认不会传输任何 UDP 数据包,所以比常规 VPN 省电很多,可以像 55 一样一直挂着使用,速度相比其他 VPN 也是压倒性优势。

img

安全模型

WireGuard 使用以下加密技术来保障数据的安全:

  • 使用 ChaCha20 进行对称加密,使用 Poly1305 进行数据验证。
  • 利用 Curve25519 进行密钥交换。
  • 使用 BLAKE2 作为哈希函数。
  • 使用 HKDF 进行解密。

WireGuard 的加密技术本质上是 Trevor PerrinNoise 框架的实例化,它简单高效,其他的 VPN 都是通过一系列协商、握手和复杂的状态机来保障安全性。WireGuard 就相当于 VPN 协议中的 qmail,代码量比其他 VPN 协议少了好几个数量级。

密钥管理

WireGuard 通过为每个对等节点提供简单的公钥和私钥来实现双向认证,每个对等节点在设置阶段生成密钥,且只在对等节点之间共享密钥。每个节点除了公钥和私钥,不再需要其他证书或预共享密钥。

在更大规模的部署中,可以使用 AnsibleKubernetes Secrets 等单独的服务来处理密钥的生成、分发和销毁。

如果你不想在 wg0.conf 配置文件中直接硬编码,可以从文件或命令中读取密钥,这使得通过第三方服务管理密钥变得更加容易:

[Interface]
...
PostUp = wg set %i private-key /etc/wireguard/wg0.key <(cat /some/path/%i/privkey)

从技术上讲,多个服务端之间可以共享相同的私钥,只要客户端不使用相同的密钥同时连接到两个服务器。但有时客户端会需要同时连接多台服务器,例如,你可以使用 DNS 轮询来均衡两台服务器之间的连接,这两台服务器配置相同。大多数情况下,每个对等节点都应该使用独立的的公钥和私钥,这样每个对等节点都不能读取到对方的流量,保障了安全性。

搭建使用与配置详解

快速开始

安装

# Ubuntu ≥ 18.04
$ apt install wireguard

在中继服务器上开启 IP 地址转发:

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.proxy_arp = 1" >> /etc/sysctl.conf
sysctl -p /etc/sysctl.conf

添加 iptables 规则,允许本机的 NAT 转换:

iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i wg0 -o wg0 -m conntrack --ctstate NEW -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.0.2.0/24 -o eth0 -j MASQUERADE

需要把 eth0 改成你实际使用的网卡接口名称。

配置文件

配置文件可以放在任何路径下,但必须通过绝对路径引用。默认路径是 /etc/wireguard/wg0.conf

生成密钥

#生成私钥
$ wg genkey > example.key

# 生成公钥
$ wg pubkey < example.key > example.key.pub

启动与停止

$ wg-quick up /full/path/to/wg0.conf
$ wg-quick down /full/path/to/wg0.conf

# 启动/停止 VPN 网络接口
$ ip link set wg0 up
$ ip link set wg0 down

# 注册/注销 VPN 网络接口
$ ip link add dev wg0 type wireguard
$ ip link delete dev wg0

# 注册/注销 本地 VPN 地址
$ ip address add dev wg0 192.0.2.3/32
$ ip address delete dev wg0 192.0.2.3/32

# 添加/删除 VPN 路由
$ ip route add 192.0.2.3/32 dev wg0
$ ip route delete 192.0.2.3/32 dev wg0

查看信息

# 查看系统 VPN 接口信息
$ ip link show wg0

# 查看 VPN 接口详细信息
$ wg show all
$ wg show wg0

# 查看 VPN 接口地址
$ ip address show wg0

路由

# 查看系统路由表
$ ip route show table main
$ ip route show table local

# 获取到特定 IP 的路由
$ ip route get 192.0.2.3

一键安装

一键安装请参考这个项目:WireGuard installer

配置详解

WireGuard 使用 INI 语法作为其配置文件格式。配置文件可以放在任何路径下,但必须通过绝对路径引用。默认路径是 /etc/wireguard/wg0.conf

配置文件的命名形式必须为 ${WireGuard 接口的名称}.conf。通常情况下 WireGuard 接口名称以 wg 为前缀,并从 0 开始编号,但你也可以使用其他名称,只要符合正则表达式 ^[a-zA-Z0-9_=+.-]{1,15}$ 就行。

你可以选择使用 wg 命令来手动配置 VPN,但一般建议使用 wg-quick,它提供了更强大和用户友好的配置体验,可以通过配置文件来管理配置。

下面是一个配置文件示例:

[Interface]
# Name = node1.example.tld
Address = 192.0.2.3/32
ListenPort = 51820
PrivateKey = localPrivateKeyAbcAbcAbc=
DNS = 1.1.1.1,8.8.8.8
Table = 12345
MTU = 1500
PreUp = /bin/example arg1 arg2 %i
PostUp = /bin/example arg1 arg2 %i
PreDown = /bin/example arg1 arg2 %i
PostDown = /bin/example arg1 arg2 %i

[Peer]
# Name = node2-node.example.tld
AllowedIPs = 192.0.2.1/24
Endpoint = node1.example.tld:51820
PublicKey = remotePublicKeyAbcAbcAbc=
PersistentKeepalive = 25

[Interface]

这一节定义本地 VPN 配置。例如:

本地节点是客户端,只路由自身的流量,只暴露一个 IP。

[Interface]
# Name = phone.example-vpn.dev
Address = 192.0.2.5/32
PrivateKey = <private key for phone.example-vpn.dev>

本地节点是中继服务器,它可以将流量转发到其他对等节点(peer),并公开整个 VPN 子网的路由。

[Interface]
# Name = public-server1.example-vpn.tld
Address = 192.0.2.1/24
ListenPort = 51820
PrivateKey = <private key for public-server1.example-vpn.tld>
DNS = 1.1.1.1
  1. Name

这是 INI 语法中的标准注释,用于展示该配置部分属于哪个节点。这部分配置会被 WireGuard 完全忽略,对 VPN 的行为没有任何影响。

  1. Address

定义本地节点应该对哪个地址范围进行路由。如果是常规的客户端,则将其设置为节点本身的单个 IP(使用 CIDR 指定,例如 192.0.2.3/32);如果是中继服务器,则将其设置为可路由的子网范围。

例如:

  • 常规客户端,只路由自身的流量:Address = 192.0.2.3/32

  • 中继服务器,可以将流量转发到其他对等节点(peer):Address = 192.0.2.1/24

  • 也可以指定多个子网或 IPv6 子网:Address = 192.0.2.1/24,2001:DB8::/64

  1. ListenPort

当本地节点是中继服务器时,需要通过该参数指定端口来监听传入 VPN 连接,默认端口号是 51820。常规客户端不需要此选项。

  1. PrivateKey

本地节点的私钥,所有节点(包括中继服务器)都必须设置。不可与其他服务器共用。

私钥可通过命令 wg genkey > example.key 来生成。

  1. DNS

通过 DHCP 向客户端宣告 DNS 服务器。客户端将会使用这里指定的 DNS 服务器来处理 VPN 子网中的 DNS 请求,但也可以在系统中覆盖此选项。例如:

  • 如果不配置则使用系统默认 DNS

  • 可以指定单个 DNS:DNS = 1.1.1.1

  • 也可以指定多个 DNS:DNS = 1.1.1.1,8.8.8.8

  1. Table

定义 VPN 子网使用的路由表,默认不需要设置。该参数有两个特殊的值需要注意:

  • Table = off : 禁止创建路由
  • Table = auto(默认值) : 将路由添加到系统默认的 table 中,并启用对默认路由的特殊处理。

例如:Table = 1234

  1. MTU

定义连接到对等节点(peer)的 MTU(Maximum Transmission Unit,最大传输单元),默认不需要设置,一般由系统自动确定。

  1. PreUp

启动 VPN 接口之前运行的命令。这个选项可以指定多次,按顺序执行。

例如添加路由:PreUp = ip rule add ipproto tcp dport 22 table 1234

  1. PostUp

启动 VPN 接口之后运行的命令。这个选项可以指定多次,按顺序执行。

例如:

  • 从文件或某个命令的输出中读取配置值:

    PostUp = wg set %i private-key /etc/wireguard/wg0.key <(some command here)
    
  • 添加一行日志到文件中:

    PostUp = echo "$(date +%s) WireGuard Started" >> /var/log/wireguard.log
    
  • 调用 WebHook:

    PostUp = curl https://events.example.dev/wireguard/started/?key=abcdefg
    
  • 添加路由:

    PostUp = ip rule add ipproto tcp dport 22 table 1234
    
  • 添加 iptables 规则,启用数据包转发:

    PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    
  • 强制 WireGuard 重新解析对端域名的 IP 地址:

    PostUp = resolvectl domain %i "~."; resolvectl dns %i 192.0.2.1; resolvectl dnssec %i yes
    
  1. PreDown

停止 VPN 接口之前运行的命令。这个选项可以指定多次,按顺序执行。

例如:

  • 添加一行日志到文件中:

    PreDown = echo "$(date +%s) WireGuard Going Down" >> /var/log/wireguard.log
    
  • 调用 WebHook:

    PreDown = curl https://events.example.dev/wireguard/stopping/?key=abcdefg
    
  1. PostDown

停止 VPN 接口之后运行的命令。这个选项可以指定多次,按顺序执行。

例如:

  • 添加一行日志到文件中:

    PostDown = echo "$(date +%s) WireGuard Going Down" >> /var/log/wireguard.log
    
  • 调用 WebHook:

    PostDown = curl https://events.example.dev/wireguard/stopping/?key=abcdefg
    
  • 删除 iptables 规则,关闭数据包转发:

    PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
    

[Peer]

定义能够为一个或多个地址路由流量的对等节点(peer)的 VPN 设置。对等节点(peer)可以是将流量转发到其他对等节点(peer)的中继服务器,也可以是通过公网或内网直连的客户端。

中继服务器必须将所有的客户端定义为对等节点(peer),除了中继服务器之外,其他客户端都不能将位于 NAT 后面的节点定义为对等节点(peer),因为路由不可达。对于那些只为自己路由流量的客户端,只需将中继服务器作为对等节点(peer),以及其他需要直接访问的节点。

举个例子,在下面的配置中,public-server1 作为中继服务器,其他的客户端有的是直连,有的位于 NAT 后面:

  • public-server1(中继服务器)

    [peer] : public-server2, home-server, laptop, phone

  • public-server2(直连客户端)

    [peer] : public-server1

  • home-server(客户端位于 NAT 后面)

    [peer] : public-server1, public-server2

  • laptop(客户端位于 NAT 后面)

    [peer] : public-server1, public-server2

  • phone(客户端位于 NAT 后面)

    [peer] : public-server1, public-server2

配置示例:

  • 对等节点(peer)是路由可达的客户端,只为自己路由流量

    [Peer]
    # Name = public-server2.example-vpn.dev
    Endpoint = public-server2.example-vpn.dev:51820
    PublicKey = <public key for public-server2.example-vpn.dev>
    AllowedIPs = 192.0.2.2/32
    
  • 对等节点(peer)是位于 NAT 后面的客户端,只为自己路由流量

    [Peer]
    # Name = home-server.example-vpn.dev
    Endpoint = home-server.example-vpn.dev:51820
    PublicKey = <public key for home-server.example-vpn.dev>
    AllowedIPs = 192.0.2.3/32
    
  • 对等节点(peer)是中继服务器,用来将流量转发到其他对等节点(peer)

    [Peer]
    # Name = public-server1.example-vpn.tld
    Endpoint = public-server1.example-vpn.tld:51820
    PublicKey = <public key for public-server1.example-vpn.tld>
    # 路由整个 VPN 子网的流量
    AllowedIPs = 192.0.2.1/24
    PersistentKeepalive = 25
    
  1. Endpoint

指定远端对等节点(peer)的公网地址。如果对等节点(peer)位于 NAT 后面或者没有稳定的公网访问地址,就忽略这个字段。通常只需要指定中继服务器Endpoint,当然有稳定公网 IP 的节点也可以指定。例如:

  • 通过 IP 指定:

    Endpoint = 123.124.125.126:51820
    
  • 通过域名指定:

    Endpoint = public-server1.example-vpn.tld:51820
    
  1. AllowedIPs

允许该对等节点(peer)发送过来的 VPN 流量中的源地址范围。同时这个字段也会作为本机路由表中 wg0 绑定的 IP 地址范围。如果对等节点(peer)是常规的客户端,则将其设置为节点本身的单个 IP;如果对等节点(peer)是中继服务器,则将其设置为可路由的子网范围。可以使用 , 来指定多个 IP 或子网范围。该字段也可以指定多次。

当决定如何对一个数据包进行路由时,系统首先会选择最具体的路由,如果不匹配再选择更宽泛的路由。例如,对于一个发往 192.0.2.3 的数据包,系统首先会寻找地址为 192.0.2.3/32 的对等节点(peer),如果没有再寻找地址为 192.0.2.1/24 的对等节点(peer),以此类推。

例如:

  • 对等节点(peer)是常规客户端,只路由自身的流量:

    AllowedIPs = 192.0.2.3/32
    
  • 对等节点(peer)是中继服务器,可以将流量转发到其他对等节点(peer):

    AllowedIPs = 192.0.2.1/24
    
  • 对等节点(peer)是中继服务器,可以转发所有的流量,包括外网流量和 VPN 流量,可以用来干嘛你懂得:

    AllowedIPs = 0.0.0.0/0,::/0
    
  • 对等节点(peer)是中继服务器,可以路由其自身和其他对等节点(peer)的流量:

    AllowedIPs = 192.0.2.3/32,192.0.2.4/32
    
  • 对等节点(peer)是中继服务器,可以路由其自身的流量和它所在的内网的流量:

    AllowedIPs = 192.0.2.3/32,192.168.1.1/24
    
  1. PublicKey

对等节点(peer)的公钥,所有节点(包括中继服务器)都必须设置。可与其他对等节点(peer)共用同一个公钥。

公钥可通过命令 wg pubkey < example.key > example.key.pub 来生成,其中 example.key 是上面生成的私钥。

例如:PublicKey = somePublicKeyAbcdAbcdAbcdAbcd=

  1. PersistentKeepalive

如果连接是从一个位于 NAT 后面的对等节点(peer)到一个公网可达的对等节点(peer),那么 NAT 后面的对等节点(peer)必须定期发送一个出站 ping 包来检查连通性,如果 IP 有变化,就会自动更新Endpoint

例如:

  • 本地节点与对等节点(peer)可直连:该字段不需要指定,因为不需要连接检查。
  • 对等节点(peer)位于 NAT 后面:该字段不需要指定,因为维持连接是客户端(连接的发起方)的责任。
  • 本地节点位于 NAT 后面,对等节点(peer)公网可达:需要指定该字段 PersistentKeepalive = 25,表示每隔 25 秒发送一次 ping 来检查连接。

Gnome

GNOME 系统设置面板(gnome-control-center)和 GNOME 应用使用 dconf 配置系统存储设置。您可以使用 gsettingsdconf 命令行工具直接访问 dconf 数据库。这也可以让你修改用户界面不公开的设置。

GNOME 桌面拥有强大的搜索功能,按 Super 键并搜索一些东西,可以进入“Settings-Search”中来设置可以搜索的内容和顺序。

Do Not Disturb 使通知只在消息栏中,不会在桌面上弹出。

Gnome 3 自动切换的壁纸会有一个有时钟小图标。

Dconf

backup dconf

Install dconf and try the command below

dconf dump / > full-backup

If it doesn’t work, try with -f flag. If you only want gnome related settings try this

dconf dump /org/gnome > gnome-backup

If you use custom theme and icon, backup those separately.

Restore

  • Full restore dconf load / < full-backup
  • Gnome only restore dconf load /org/gnome < gnome-backup

浏览

GNOME Shell cheat sheet 中解释了如何高效地使用 GNOME shell,它展示了 GNOME shell 的特色和快捷键,包括切换任务,使用键盘,窗口控制,面板,概览模式等等。以下是部分常用的快捷键:

  • Super + m:显示消息托盘
  • Super + a:显示应用程序菜单
  • Alt- + Tab:切换当前使用的应用
  • Alt- + ` (美式键盘 Tab 上面的按键):切换前台应用程序的窗口
  • Alt + F2,然后输入 rrestart:在图形界面出问题时重启界面(仅用于 X/传统 模式,不适用于 Wayland 模式)。也可通过此运行后台应用,如 cfw。

Gedit

编码

直接打开gedit(非通过文件打开),点击左上角 Open,点击左下角 Automatically Detected,下拉选择 Add or Remove...,将简体中文编码都选上。

或者:

$ gsettings list-keys org.gnome.gedit.preferences.encodings
candidate-encodings
$ gsettings set org.gnome.gedit.preferences.encodings candidate-encodings "['UTF-8', 'ISO-8859-15', 'UTF-16', 'GBK', 'GB18030', 'GB2312']"

配置

  • 在 Perferences => View => Text Wrapping,都启用。
  • 在 Perferences => Editor => Tap Stops,把 Tab width 设置为 2,勾选 Insert spaces instead of tabs。

Nautilus

Files 是 GNOME 桌面环境的默认文件管理器。文件试图提供一种简化的方法来管理文件和应用程序。Files 在 3.6 版之前被称为 Nautilus。该应用程序被赋予了新的描述性名称,每种受支持的语言都有一个名称。 Nautilus 这个名称仍然在许多地方使用,例如可执行文件名称,某些程序包名称,某些桌面条目和某些 GSettings 模式。

快捷键

有时候鼠标操作效率低,比如新建标签页(汉堡菜单 > 新建标签页),我们要移动两次光标点两下,如果使用快捷键 Ctrl+T,一次就能迅速完成操作。所以,使用快捷键能提高效率。另一个让你多使用键盘快捷键的理由可能是,预防鼠标手。如果您经常使用某个软件,那么有必要学习它的快捷键,如果偶尔使用就没必要浪费时间。

Ctrl+F1,查看 Files 快捷键。建议您参考列表多加练习。一些常用快捷键:

快捷键 功能
Ctrl T New tab
Ctrl N New window
Ctrl W Close window or tab
Ctrl F Search
~ Location bar with home location
/ Location bar with root location
Ctrl L Enter location
Backspace Go Back to a Previous Folder
Ctrl + Zoom in
Ctrl - Zoom out
Ctrl 0 Reset zoom
Ctrl H Show/hide hidden files
F2 Rename
Delete Move to trash
Shift Delete Delete permanently
Ctrl C Copy
Ctrl V Paste
Ctrl X Cut
Ctrl Z Undo
Shift Ctrl Z Redo
Ctrl A Select all
Shift Ctrl I Invert selection
Ctrl Q Quit

从右键菜单创建新文档

只需要将模板文件放到用户根目录下的 Templates / 模板 文件夹里面。比如:

touch ~/Templates/sh.sh
touch ~/Templates/python.py
touch ~/Templates/Markdown.md

当你右键时,就可以直接以该模板新建文件。

Templates 目录可以在 ~/.config/user-dirs.dirs 中配置。默认为:

XDG_TEMPLATES_DIR="$HOME/Templates"

你可以设置为其他目录。比如我的为:

XDG_TEMPLATES_DIR="/DATA/Templates"

/DATA 不在系统分区,是一个单独的分区,我专门用来存放个人数据。

直接搜索匹配

常用的目录可以添加为书签,但访问其他目录时,我们经常是按路径逐个点击文件夹。对于文件夹路径较深或者周围有其他文件夹干扰的情况,操作起来其实非常低效。不知你是否意识到、思考过。

人们习惯鼠标操作后,往往不会再去思考如何提升效率,一直呆在舒适区域:这个我已经会用了。但是,有一些你不知道的技巧能够提高办事效率。

实际上,只要你身处 Files 中,直接输入英文字符即可搜索匹配。Files 像浏览器一样合并了搜索栏和地址栏,你可以直接输入 关键词 或者 路径 。但是,中文关键词需要在搜索栏(Ctrl+F)中输入。

一个实例:打开 GNOME 桌面系统图标所在文件夹 /usr/share/icons

方法一:鼠标点击 / usr share 直接输入 icons 然后 Enter 打开。

这是目标文件夹周围有其他文件夹干扰的情况。

方法二:Files 中直接输入 /usr/share/icons(操作时可利用 Tab 自动补全)。

这是路径较深的情况。

Gnome Tweaks

GNOME 桌面有称为“扩展”的小插件或附加组件,学会使用 GNOME 扩展来扩展系统的可用性。安装必须的 packages:

sudo apt install gnome-tweaks gnome-shell-extensions chrome-gnome-shell -y

主题相关目录:

  • 主题目录: /usr/share/themes~/.themes
  • 图标鼠标目录: /usr/share/icons~/.icons
  • 壁纸: /usr/share/background , /usr/share/wallpapers

主题选择:Skeuomorphism vs Flat Design vs Material Design

如果要在不同发行版上统一 Gnome 界面,那么最好的方法就是使用自定义主题了。

Ubuntu Dock

Ubuntu Dock 就是 Dash to Dock。安装:

sudo apt-get install  gnome-shell-extension-dashtodock

重启,在 Extension 中设置 Dash to Dock,Dash to Dock 与 Ubuntu Dock 只能开启一个,否则有两个 Dock,但是就算关闭 Dash to Dock,Dash to Dock 设置依旧起作用到 Ubuntu Dock。

重新登录。

GSConnect

Files and links. Shared between devices.

Firewall Blocking Port

使用 ufw:

sudo ufw allow proto tcp from 192.168.2.0/24 to any port 1714:1764
sudo ufw allow proto udp from 192.168.2.0/24 to any port 1714:1764
sudo ufw reload

有时候正确设置了防火墙,还是会发送文件失败,可以考虑重启应用。

mounting does not work

$ sftp -P 1740 kdeconnect@192.168.0.105
Unable to negotiate with 192.168.88.245 port 1740: no matching host key type found. Their offer: ssh-rsa
Connection closed.  
Connection closed
$ vim ~/.ssh/config
Host 192.168.0.*
   HostkeyAlgorithms +ssh-rsa
   PubkeyAcceptedAlgorithms +ssh-rsa
$ ssh kdeconnect@192.168.0.105 -p 1740

After that the mounting works again.

GSConnect cannot send multiple files at once

GSConnect cannot send multiple files at once. If I try sending multiple files to my phone, only one file is received by my phone.

GSConnect shows “Transfer Successful” notification only for the first file, and “Transferring File” notifications for the other files remain.

Files Integration

sudo apt install python3-nautilus gir1.2-nautilus-3.0
nautilus -q && nautilus

KDE Connect

sudo apt install kdeconnect nautilus-kdeconnect

有时候总也连不上,可以通过路由器将 PC 端 IP 固定,然后在 Android 端用 Add devices by IP 连接。

Desktop Icons NG (DING)

with these advantages:

  • Drag’n’Drop, both inside the desktop, between desktop and applications, and nautilus windows
  • Allows to use “Open with…” option with several files
  • When hovering or clicking on an icon with a name too large to fit, it shows the full name
  • Doesn’t hang the compositor when there is too much activity in the desktop folder

Lunar Calendar 农历

sudo apt install gir1.2-lunar-date-2.0
sudo cp /usr/share/locale/zh_CN/LC_MESSAGES/lunar-date.mo /usr/share/locale/en/LC_MESSAGES/

你正在必须把系统语言改成中文它才会显出来:-(

PaperWM

Tiled scrollable window management for Gnome Shell

Something went wrong” at the end has been happening for a while and doesn’t necessarily mean the install failed. It might just fail to enable and it will start the next time you restart gnome-shell (e.g. by logging out and in) or enable the extension manually. I believe there is already a ticket somewhere about this.

其他扩展推荐

  • NetSpeed: Displays Internet Speed
  • Clipboard Indicator: Clipboard Manager extension for Gnome-Shell - Adds a clipboard indicator to the top panel, and caches clipboard history.
  • Coverflow Alt-Tab: Replacement of Alt-Tab, iterates through windows in a cover-flow manner.
  • Bluetooth Quick Connect: Allow to connect to paired devices from gnome control panel.
  • Frippery Move Clock: Move clock to left of status menu button
  • Input Method Panel: Input Method Panel using KDE’s kimpanel protocol for Gnome-Shell
  • Lock Keys: Numlock & Capslock status on the panel
  • OpenWeather: Weather extension to display weather information from https://openweathermap.org/ or https://darksky.net for almost all locations in the world. 需设置 Location,Units 为公制单位,Layout为Right
  • Panel Date Format: Allows to customize the date format on the panel.
  • Refresh Wifi Connections: This extension adds a refresh button to the Wi-Fi connection selection dialog to manually request for a network scan.
  • Screenshot Tool: Conveniently create, copy, store and upload screenshots. Please log out and log in again after updating.
  • Sound Input & Output Device ChooserLivepatch: Shows a list of sound output and input devices (similar to gnome sound settings) in the status menu below the volume slider.
  • Status Area Horizontal Spacing: Reduce the horizontal spacing between icons in the top-right status area
  • Unite: Unite is a GNOME Shell extension which makes a few layout tweaks to the top panel and removes window decorations to make it look like Ubuntu Unity Shell.
  • User Themes: Load shell themes from user directory.
  • Vitals: A glimpse into your computer’s temperature, voltage, fan speed, memory usage, processor load, system resources, network speed and storage stats. This is a one stop shop to monitor all of your vital sensors. Uses asynchronous polling to provide a smooth user experience.
  • Removable Drive Menu: A status menu for accessing and unmounting removable devices.
  • Places Status Indicator: Add a menu for quickly navigating places in the system. This extension is part of Classic Mode and is officially supported by GNOME. Please do not report bugs using the form below, use GNOME’s GitLab instance instead.
  • Recent Items
  • gTile: Tile windows on a grid.
  • Top Panel Workspace Scroll: Change workspaces by scrolling over the top panel
  • Workspace Indicator: Put an indicator on the panel signaling in which workspace you are, and give you the possibility of switching to another one.
  • Auto Move Windows: Move applications to specific workspaces when they create windows.
  • Applications Menu: Add a category-based menu for applications. This extension is part of Classic Mode and is officially supported by GNOME. Please do not report bugs using the form below, use GNOME’s GitLab instance instead.
  • Fly-Pie: A marking menu which can be used to launch applications, simulate hotkeys, open URLs and much more.
  • AppIndicator and KStatusNotifierItem Support: Adds AppIndicator, KStatusNotifierItem and legacy Tray icons support to the Shell
  • Time ++: A todo.txt manager, time tracker, timer, stopwatch, pomodoro, and alarm clock. 番茄钟
  • BackSlide: Automatic background-image (wallpaper) slideshow for Gnome Shell
  • Remove Alt+Tab Delay v2: Another extension that removes the 0.15 second popup delay in switcher pop-ups. This extension is actively maintained.
  • EasyScreenCast : This extension simplifies the use of the video recording function integrated in gnome shell, allows quickly to change the various settings of the desktop recording.
  • Hide Top Bar: Hides the top bar, except in overview. However, there is an option to show the panel whenever the mouse pointer approaches the edge of the screen. And if “intellihide” is enabled, the panel only hides when a window takes the space.
  • Battery Time: Show the remaining time until fully charged/discharged instead of the battery charge in percent in the panel.
  • Caffeine: Disable the screensaver and auto suspend
  • Todo.txt: A Gnome shell interface for todo.txt.
  • Internet Radio: Listen to an Internet Radio Stream
  • ibus font setting: use ibus font setting of ibus setup dialog to enhance the user experience

遗留名称

注意: 一些 GNOME 程序在文档和对话框中的名称已经更改,但执行文件名称却没有。下面表格列出了一些这样的应用程序。

提示: 在搜索栏中搜索应用的遗留名称将成功找到对应的应用,例如搜索 nautilus 将返还 文件

当前 遗留
文件 Nautilus
Web Epiphany
视频 Totem
主菜单 Alacarte
文档查看器 Evince
磁盘使用情况分析器 Baobab
图像查看器 EoG (Eye of GNOME)
密码和密钥 Seahorse

默认应用程序

mime类型文件

存在于以下的两个路径:

  • /usr/share/mime/
  • ~/.local/share/mime/

例如:/usr/share/mime/text/makrdown.xml

Get the mime type of a file

file --mime-type -b filename

应用程序 desktop文件

存在于以下的两个路径:

  • /usr/share/applications/
  • ~/.local/share/applications/

例如 typora.desktop 文件:

[Desktop Entry]
# 应用名称,即开始菜单中的名称
Type=ApplicationName=name 
# 应用执行文件位置
Exec=appPath
# 应用图标位置
Icon=typora
# 是否显示终端
Terminal=false
# 所属分类
StartupNotify=trueCategories=Office
# MIME 类型
MimeType=text/x-markdown

应用图标

默认位置为 ~/.local/share/icons,一个直接放入,如 ~/.local/share/icons/typora.png,一个根据分辨率放入,如 ~/.local/share/icons/hicolor/256x256/typora.png

应用程序默认关联文件

存在于以下的两个路径:

  • /usr/share/applications/mimeapps.list
  • ~/.local/share/applications/mimeapps.list

例如

text/plain=org.gnome.gedit.desktop
text/html=firefox.desktop

桌面卡死

总的来说,就是杀死相关进程,或者避免使用造成卡死相关软件。

  • 选择其他 tty:

    pkill Xorg 
    

    pkill 用于杀死一个进程,与 kill 不同的是它会杀死指定名字的所有进程。kill 命令杀死指定进程 PID,需要配合 ps 使用。

  • 安全重启:同时按住 Ctrl 和 Alt 键,按住不要放,按一下 SysRq 键(有的键盘是PrtSc),按一下 R 键,按一下 E 键,依次按下 I , S , U , B 键。

  • 解决 Ubuntu 经常卡死:ubuntu 的卡死可能与显卡驱动不兼容有关。用 nvidia 代替 nouveau显卡驱动。其中 nvidia-driver-470-server 是 server 版,最好用 nvidia-driver-470

NVIDIA

NVIDIA drivers on Ubuntu

First, detect the model of your nvidia graphic card and the recommended driver.

ubuntu-drivers devices

If you agree with the recommendation feel free to use the ubuntu-drivers command again to install all recommended drivers:

sudo ubuntu-drivers autoinstall

NVIDIA Optimus

NVIDIA Optimus 是一项允许英特尔(Intel)集成图形处理器(GPU)和英伟达(NVIDIA)独立图形处理器置入并通过一台笔记本电脑访问的技术。

PRIME Synchronization

You can enable PRIME synchronization to prevent screen tearing. It requires:

  • Linux kernel 4.5 or higher;
  • X server 1.19 or higher;
  • NVIDIA driver 370.23 or higher.

PRIME synchronization will be enabled automatically after you enable KMS for nvidia-drm module.

  1. Add this line to the end of /etc/modprobe.d/nvidia.conf:

    options nvidia-drm modeset=1
    
  2. Regenerate your initramfs image by running:

    sudo update-initramfs -u
    
  3. Reboot.

要检查重新启动后以前的更改是否有效,请运行命令:

$ sudo cat /sys/module/nvidia_drm/parameters/modeset
Y

see more about nvidia on uat BinaryDriverHowto/Nvidia

NVIDIA PowerMizer

$ nvidia-settings -q GpuPowerMizerMode
  Attribute 'GPUPowerMizerMode' (rastating-PC:1[gpu:0]): 0.
    Valid values for 'GPUPowerMizerMode' are: 0, 1 and 2.
    'GPUPowerMizerMode' can use the following target types: GPU.

$ nvidia-settings -a "[gpu:0]/GpuPowerMizerMode=1"
  Attribute 'GPUPowerMizerMode' (rastating-PC:1[gpu:0]) assigned value 1.

$ nvidia-settings -q GpuPowerMizerMode
  Attribute 'GPUPowerMizerMode' (rastating-PC:1[gpu:0]): 1.
    Valid values for 'GPUPowerMizerMode' are: 0, 1 and 2.
    'GPUPowerMizerMode' can use the following target types: GPU.

添加到开机启动

  • Name:NVIDIA X Server Performance Settings

  • Command:/usr/bin/nvidia-settings -a "[gpu:0]/GpuPowerMizerMode=1"

密钥环

如果你用过 Ubuntu 或者其他的 Linux 发行版里的自动登录功能, 你可能遇到过这种弹出消息:

请输入密码以解锁你的登录密钥环

登录密钥环在你登录系统时未解锁。

Enter Password To Unlock Your Login Keyring Ubuntu

如果你一直点击取消,它会不断弹出几次才会消失。你可能想知道,为什么你会一直看到这个密钥环信息呢?

让我来告诉你吧。它其实不是错误,而是一个安全特性。

奇怪吗?下面就让我来解释下 Linux 里的密钥环概念。

密钥环是什么,为什么需要它?

在现实生活中你为什么要用钥匙环(也叫钥匙链)?你用它把一把或多把钥匙串到一起, 以便于携带和查找。

Linux 里也是类似的。密钥环特性使你的系统可以将各种密码放在一起,并将其保存在一个地方。

大多数 Linux 桌面环境,如 GNOME、KDE、Xfce 等采用 GNOME 密钥环来提供这个功能。

该密钥环保存了 ssh 密钥、GPG 密钥以及使用此功能的应用程序(例如 Chromium 浏览器)的密钥。默认情况下,“密钥环”通过主密码来保护,该密码通常是帐户的登录密码。

系统上的每个用户都有自己的密钥环,(通常)密码与用户帐户本身的密码相同。当你使用密码登录系统时,你的密匙环将使用你帐户的密码自动解锁。

当你启用 Ubuntu 中的自动登录功能时时,就有问题了。这意味着你无需输入密码即可登录系统。在这种情况下,你的密钥环不会自动解锁。

密钥环是一个安全特性

记得我说过密钥环是一个安全特性吗?现在想象一下你在 Linux 电脑上开启了自动登录功能。有权访问你电脑的任何人无需密码就能进入你的系统。但是你可能不会在意,因为你只是用它来访问互联网。

但是,如果你在 Ubuntu 中使用 Chromium 或 Google Chrome 之类的浏览器,并使用它来保存各种网站的登录密码,那么你将遇到麻烦。任何人都可以使用浏览器并利用你在浏览器中保存的密码登录网站。这不很危险吗?

这就是为什么当你使用 Chrome 时,它将反复地提示你先解锁密钥环。这确保了只有知道密钥环密码(即账户密码)的人才能使用在浏览器中保存的密码来登录它们相关的网站。

如果你反复取消解锁密钥环的提示,它最终将消失,并允许你使用浏览器。但是,保存的密码将不会被解锁,你在 Chromium/Chome 浏览器上将会看到“同步暂停”的提示。

如果密钥环一直存在,为什么你从来没有见过它呢?

如果你在你的 Linux 系统上从没见过它的话,这个问题就很有道理。

如果你从没有用过自动登录功能(或者修改你的账户密码),你可能都没有意识到这个特性的存在。

这是因为当你通过你的密码登录系统时,你的密钥环被你的账户密码自动解锁了。

Ubuntu(和其他发行版)在执行普通的管理任务如修改用户、安装新软件等需要输入密码,无论你是否是自动登录的。但是对于日常任务像使用浏览器,它不需要输入密码因为密钥环已经被解锁了。

当你切换到自动登录时,你不再需要输入登录密码。这意味着密钥环没有被自动解锁,因此当你使用利用了密钥环特性的浏览器时,它将提示你来解锁密钥环。

你可以轻松地管理密钥环和密码

这个密钥环放在哪里?它的核心是一个守护任务(一个后台自动运行的程序)。

别担心。你不必通过终端来操作守护任务。大多数桌面环境都自带一个可以和这个守护进程进行交互的图形化应用程序。KDE 上有 KDE 钱包,GNOME 和其他桌面上叫做“密码和密钥”(Password And Keys)。

你可以用这个 GUI 程序来查看哪些应用程序在用密钥环来管理/保护密码。

你可以看到,我的系统有自动创建的登录密钥环。也有一个存储 GPG 和 SSH 密钥的密钥环。那个证书用来保存证书机构颁发的证书(如 HTTPS 证书)。

Password and Keys application in Ubuntu

你也可以使用这个应用程序来手动保存网站的密码。

这里有一个潜在的问题,如果你格式化你的系统,手动保存的密码必然会丢失。通常,你会备份你的个人文件,但并不是所有的用户特定数据,如密钥环文件。

有一种办法能解决它。密钥环数据通常保存在 ~/.local/share/keyrings 目录。在这里你可以看到所有的密钥环,但是你不能直接看到它们的内容。如果你移除密钥环的密码(我会在这篇文章的后面描述操作步骤),你可以像一个普通的文本文件一样读取密钥环的内容。你可以将这个解锁后的密钥环文件完整地复制下来,并在其他的 Linux 机器上运行“密码和密钥”应用程序导入到其中。

总结一下目前为止所学的内容:

  • 大多数 Linux 系统缺省已经安装并激活了密钥环特性
  • 系统上的每个用户都拥有他自己的密钥环
  • 密钥环通常是用账户密码锁定的(保护)
  • 当你通过密码登录时密钥环会被自动解锁
  • 对于自动登录,密钥环不会自动解锁,因此当你试图使用依赖密钥环的应用程序时会被提示先解锁它
  • 并不是所有的浏览器或应用程序利用了密钥环特性
  • (Linux 上)安装一个 GUI 程序可以和密钥环交互
  • 你可以用密钥环来手动存储加密格式的密码
  • 你可以自己修改密钥环密码
  • 你可以通过导出(需要先解锁密钥环)并导入到其他计算机上的方式来获取手工保存的密码。

修改密钥环密码

假设你修改了你的账户密码。当你登录时,你的系统试图通过新的登录密码来自动解锁密钥环。但是密钥环还在使用老的登录密码。

这种情况下,你可以修改密钥环密码为新的登录密码,这样密码环才能在你登录系统时自动解锁。

  • 从菜单中打开“密码和密钥”应用程序
  • 在“Login”密钥环上右击并点击“修改密码”:

如果你不记得老的登录密码怎么办?

Resetting everything (delete all passwords and start new keyring):

rm ~/.local/share/keyrings/login.keyring

Then, log out and log back in. Ubuntu will automatically create a new login.keyring for you.

禁用密钥环密码

在你想用自动登录但又不想手动解锁密钥环时,你可以把禁用密钥环密码作为一个规避方法。记住你正在禁用一个安全特性,因此请三思。

操作步骤和修改密钥环相似。打开“密码和密钥”应用程序,然后修改密钥环密码。

技巧在于当它提示修改密码时,不要输入新密码,而是点击“继续”按钮。这将移除密钥环的密码。

这种方法,密钥环没有密码保护,并将一直处于解锁状态。

Gnome Apps

Sort the App Grid alphabetically

gsettings set org.gnome.shell app-picker-layout "[]"

Books

GNOME Books is a simple application to access and organize your ebooks. It is meant to be a simple and elegant replacement for using a file manager to deal with ebooks. The app supports comic books and ePub books.

sudo apt install gnome-books

e-book 需放在特定的目录,gnome-boos 自动扫描,在其他目录不扫描,而且也无法用 gnome-books file 方式打开,例如 ~/Public 目录。

Calendar

sudo apt install gnome-calendar
gsettings set org.gnome.GWeather temperature-unit centigrade