利用aria2,把树莓派变成离线下载机

0-前言

买树莓派最初的目的就是奔着实用去的,在安装并配置 aria2 和 aria2WebUI 这两天,借助了各路大神的经验分享,但在这个过程中也体会到了较大的压力,因为这些经验分享无一例外的都预设了读者是一个已经熟悉Linux基本操作的用户,所以我基本上是一边实现一边学,把Linux系统的一些基本操作都熟悉了。

完成之后,想到肯定还有和我一样的用户,更迫切的只需要“树莓派离线下载器”这一功能本身,于是写作此文,希望能讲的更加通俗易懂。如果其他和我一样的纯小白用户,不必经历我这两天的折腾,直接参照 1 ~ 4 节的内容即完成了配置,这就达到了我本文的目的。

在完成下载器全部功能后,如果你希望深入了解我让你敲的那些玩意儿究竟是干什么的,在第 5 节,我详细解释了 Linux 自定义自启动项的几种方式,在第 6 节,则附上了本文所使用到的一些 Linux 内置命令 / 第三方软件的命令。

最后安装完效果如下图:

最终效果

左侧是aria2web UI,右侧是通过SMB协议开放给局域网的下载目录(可直接运行和播放)

1-系统前提

  1. 一台已经装好树莓派官方系统Raspbian的树莓派4B(参考文章:树莓派如何完全无头(无屏无网线无键盘鼠标)安装
  2. 树莓派已启用SSH服务(在完全无头的状态下启用,请参考前一条的参考文章,在连接屏幕的方式下启用,请参考Linux中国-新手教程:如何 SSH 进入树莓派
  3. (强烈建议)把树莓派的软件源换成国内镜像站(参考文章:清华大学开源镜像站-Raspbian 镜像使用帮助,该操作需要对系统文件做一定的编辑,关于如何在Linux命令行模式下编辑文件,请跳转至本文第 6 节关于Nano的部分)

成功通过SSH登录树莓派后,我们就可以开始正式的安装了,以下 2 ~ 4 所有步骤都是在SSH里面进行的。

2-aria2

aria2本质上是一个命令行下载工具,这意味着它事实上本身并没有界面,而是运行在后台的一个服务而已,在我们这个场景里面,我们希望它默默运行在树莓派的后台里,接收我们通过Aria2 WebUI这个界面发送的下载请求并进行下载。

2.1-安装aria2

在SSH中直接依次复制下述命令运行即可:

  1. 更新软件列表 sudo apt-get update
  2. 下载aira2 sudo apt-get install aria2
  3. 检查aria2是否安装成功 aria2c --version

如果成功看到如下提示(随时间变化,版本号可能不一致),即说明aria2已经安装成功。

aria2 version 1.35.0
Copyright © 2006, 2019 Tatsuhiro Tsujikawa

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

** Configuration **
Enabled Features: BitTorrent, GZip, Message Digest, Metalink, XML-RPC
Hash Algorithms: sha-1, sha-224, sha-256, sha-384, sha-512, md5, adler32
Libraries: zlib/1.2.11 expat/2.2.6
Compiler: gcc 8.3.0
built by armv7l-unknown-linux-gnueabihf
on Mar 27 2020 18:03:29
System: Linux 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l

Report bugs to https://github.com/aria2/aria2/issues
Visit https://aria2.github.io/

2.2-编辑 aria2 的配置文件

如前所述,aria2其实是一个运行在命令行状态下的下载工具,在前述安装步骤完成之后,其实现在你的Linux(树莓派)已经可以直接下载文件了,但是我们需要的是一个图形化界面,所以需要进行如下操作,将 aria2 切换为RPC模式——不要被陌生名词吓到,简单说来我的理解就是,把 aria2 变成一个服务端,通过指定端口(默认6800)接收一切下载请求(你可以另外开一个SSH发送下载请求,也可以像我们做的一样,使用别人做好的webUI来进行图形化操作)。

操作顺序如下:

  1. 去到当前用户默认目录 cd ~
  2. 新建一个目录用来存放aria2的配置文件和用于保存下载进度的session文件 mkdir .aria2
  3. 新建配置文件: touch ~/.aria2/aria2.conf ,和session文件 touch ~/.aria2/aria2.session
  4. 编辑配置文件: nano ~/.aria2/aria2.conf ,随后会进入到一个文本编辑器,这里贴上我的配置(#后面是注释)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# 这个bt-tracker来自(全网热门公共 BitTorrent Tracker 列表合集 https://github.com/XIU2/TrackersListCollection/blob/master/README-ZH.md ),说是可以给 aria2 提供更多的做种来源,提高下载速度(不过我试了下,冷门资源还是很慢😂,只能说聊胜于无吧。)
bt-tracker=udp://retracker.lanta-net.ru:2710/announce,udp://tracker.tiny-vps.com:6969/announce,udp://tracker.torrent.eu.org:451/announce,udp://tracker3.itzmx.com:6961/announce,udp://tracker.moeking.me:6969/announce,http://tracker1.itzmx.com:8080/announce,http://tracker.nyap2p.com:8080/announce,udp://bt1.archive.org:6969/announce,udp://bt2.archive.org:6969/announce,udp://ipv4.tracker.harry.lu:80/announce,udp://explodie.org:6969/announce

## 文件保存相关 ##

# 默认的下载保存路径(可使用绝对路径或相对路径), 如果没有这行,下载路径就会是你的aria2启动位置
dir=/home/pi/Downloads

# 启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16M
#disk-cache=32M
#disk-cache=32M
# 文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc
# 预分配所需时间: none < falloc ? trunc < prealloc
# falloc和trunc则需要文件系统和内核支持
# NTFS建议使用falloc, EXT3/4建议trunc, MAC 下需要注释此项
file-allocation=prealloc
# 断点续传
continue=true

## 下载连接相关 ##

# 最大同时下载任务数, 运行时可修改, 默认:5
max-concurrent-downloads=10
# 同一服务器连接数, 添加时可指定, 默认:1
max-connection-per-server=10
# 最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M
# 假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载
min-split-size=10M
# 单个任务最大线程数, 添加时可指定, 默认:5
split=5
# 整体下载速度限制, 运行时可修改, 默认:0
#max-overall-download-limit=0
# 单个任务下载速度限制, 默认:0
#max-download-limit=0
# 整体上传速度限制, 运行时可修改, 默认:0
#max-overall-upload-limit=0
# 单个任务上传速度限制, 默认:0
#max-upload-limit=0
# 禁用IPv6, 默认:false
disable-ipv6=true

## 进度保存相关 ##

# 从会话文件中读取下载任务
input-file=/home/pi/.aria2/aria2.session
# 在Aria2退出时保存`错误/未完成`的下载任务到会话文件
save-session=/home/pi/.aria2/aria2.session
# 定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0
save-session-interval=60

## RPC相关设置 ##


# 启用RPC, 默认:false
enable-rpc=true
pause=false
rpc-allow-origin-all=true
rpc-listen-all=true
rpc-save-upload-metadata=true

# 设置的RPC授权令牌,如果你的局域网内有其他你不希望使用aria2webUI的人,将下方这条取消注释,并设置你想要的token,在后续进入webUI之后,在连接设置(connection settings)里面输入你设置的token
# rpc-secret=test


## BT/PT下载相关 ##

# 当下载的是一个种子(以.torrent结尾)时, 自动开始BT任务, 默认:true
#follow-torrent=true
# BT监听端口, 当端口被屏蔽时使用, 默认:6881-6999
listen-port=51413
# 单个种子最大连接数, 默认:55
#bt-max-peers=55
# 打开DHT功能, PT需要禁用, 默认:true
enable-dht=true
# 打开IPv6 DHT功能, PT需要禁用
#enable-dht6=false
# DHT网络监听端口, 默认:6881-6999
#dht-listen-port=6881-6999
# 本地节点查找, PT需要禁用, 默认:false
bt-enable-lpd=true
# 种子交换, PT需要禁用, 默认:true
enable-peer-exchange=false
# 每个种子限速, 对少种的PT很有用, 默认:50K
#bt-request-peer-speed-limit=50K
# 客户端伪装, 下载百度云的时候有用,目前我还没用上,因为我有PanDownload……也没遇到过需要用百度云下载大文件的时候。
peer-id-prefix=-TR2770-
user-agent=Transmission/2.92
user-agent=netdisk;4.4.0.6;PC;PC-Windows;6.2.9200;WindowsBaiduYunGuanJia

# 当种子的分享率达到这个数时, 自动停止做种, 0为一直做种, 默认:1.0
seed-ratio=1.0
#作种时间大于30分钟,则停止作种
seed-time=30
# 强制保存会话, 话即使任务已经完成, 默认:false
# 较新的版本开启后会在任务完成后依然保留.aria2文件
#force-save=false
# BT校验相关, 默认:true
#bt-hash-check-seed=true
# 继续之前的BT任务时, 无需再次校验, 默认:false
bt-seed-unverified=true
# 保存磁力链接元数据为种子文件(.torrent文件), 默认:false
bt-save-metadata=true

配置文件复制进去后(Windows可以复制上述文档后,SSH界面点击鼠标右键),按Ctrl+S保存,然后按Ctrl+X退出。

测试一下配置文件能否正常运行:aria2c --conf-path=/home/pi/.aria2/aria2.conf,如果出现如下提示即表明配置文件运行正常,可以准备使用aria2webUI了。

03/29 08:37:41 [NOTICE] IPv4 RPC: listening on TCP port 6800
03/29 08:38:41 [NOTICE] Serialized session to ‘/home/pi/.aria2/aria2.session’ successfully.

3-aria2 WebUI

其实经过前述操作,如果我们让 aria2c RPC模式的窗口始终运行在后台,已经可以通过命令行发送命令去下载文件了,webUI就是一个图形化界面,让我们不必每次下载东西都需要打开命令行。

  1. 回到我们的用户根目录 cd ~
  2. 从Github把webUI的源码(也是程序本身)下载下来 git clone https://github.com/ziahamza/webui-aria2.git(如果提示没有git,请参考如何在 Raspberry Pi 上安装 Git 进行配置和安装,因为是从Github下载,配置过程中请使用Github的帐号和密码)
  3. 下载完成后进入目录: cd webui-aria2
  4. 启动webUI: node node-server.js 如果看到如下提示,说明webUI已经成功运行了。

WebUI Aria2 Server is running on http://localhost:8888

  1. 另外打开一个SSH窗口,把第1节中的命令输入进去 aria2c --conf-path=/home/pi/.aria2/aria2.conf 并确认成功运行。
  2. 打开浏览器,使用 树莓派IP地址:8888 (如果不知道树莓派IP地址,请参考查看树莓派ip地址的几种方法,我是直接在路由器给树莓派分配了一个固定IP),即可成功访问 aria2 的 WebUI!(如下截图左侧界面)
最终效果

aria2WebUI

4-把两个应用设置为开机自启动

第3节末尾,我们打开的这两个窗口,前一个就是webUI的服务端程序,后一个就是aria2本体的服务端程序,你可以简单理解为前面那个是操作台,后面那个是引擎。

如果你关掉任意一个SSH窗口,这个webUI都将不能工作,但是我们不能每次要使用树莓派连夜下载的时候,都要这么操作一番,于是我们需要将他们后台化,并且设置为在树莓派开机的时候自动启动。

(为了后面的测试方便,把刚才的两个服务先终止掉,Ctrl+C)

  1. 安装screen应用: sudo apt-get install screen(关于这个应用的介绍请跳转6.4)
  2. 在用户根目录创建启动 aria2 的脚本: cd ~ && nano aria2.sh
  3. 复制以下脚本代码:
1
2
#!/bin/bash
screen -d -m aria2c --conf-path=/home/pi/.aria2/aria2.conf
  1. Ctrl+S 保存,Ctrl+X 退出。
  2. 在用户根目录创建启动 aria2webui的脚本 cd ~ && nano aria2webui.sh
  3. 复制以下脚本代码:
1
2
3
#!/bin/bash
cd /home/pi/webui-aria2/
screen -d -m node node-server.js
  1. 同样Ctrl+S 保存,Ctrl+X 退出。
  2. 修改权限让这两个文件可以运行: sudo chmod 755 ./aria2.shsudo chmod 755 ./aria2webui.sh
  3. 编辑crontab设置开机启动项: crontab -e
  4. 复制以下代码:
1
2
@reboot /home/pi/aria2.sh
@reboot /home/pi/aria2webui.sh
  1. 重启树莓派: sudo reboot

树莓派的重启非常快,喝口水,打开浏览器访问 树莓派IP地址:8888,没意外的话你应该就能看到aria2WebUI的界面了,以后每一次需要挂机下载,只需要给树莓派通电,并访问这个网址下载即可。


在整个操作中,我将所有文件下载目录设置为用户主目录的Downloads文件夹。

当然,我们当然不能下载到树莓派就完事了,我用的方案是:使用samba协议把Downloads文件夹开放给局域网成为一个媒体服务器,具体操作可参考:树莓派3-搭建SAMBA服务器,在配置过程中,记得将共享路径设置为/home/pi/Downloads(也就是我们在aria2.conf里面设置的默认下载路径)。

配置运行成功并添加到windows的资源管理器后,你就能看到如下图的右侧部分,所有树莓派上的 aria2 下载的文件,都会自动出现在这里,并且可以直接运行、播放、复制到本地。

最终效果

右侧是位于树莓派上的下载目录

(后面的内容写给有兴趣的朋友,如果你只需要一个下载器,在这一步成功运行之后已经可以正常使用全部功能了)

5-Raspbian(Linux)系统的三种自启动设置方式

以我查询到的信息来看,在Linux下,用户想要把自己的程序设置成开机自启动(并且挂在后台运行),至少有如下三个方案(复杂度由高到低):

5.1-利用系统级的自启动rcN.D

参考文章关于Ubuntu运行级别、开机启动脚本的说明,我大概看了一圈,觉得这方案太复杂了😂

5.2-利用自定义服务,实现需要的程序开机自启

什么是服务?我的理解就是一种后台进程,可以为用户和系统提供持续性的服务(菜鸟说法,如有不妥请懂行的不吝赐教)。

/lib/systemd/system/usr/lib/systemd/system 下面,你可以看到很多.service后缀的文件,这就是目前系统中的服务,我们要做的就是自己制作一个服务文件,这个服务文件会一直在后台监视着我们需要的那个应用有没有在运行,如果被意外终止,它还可以帮我们自动重启那个应用(这一点来说,比下一个方案的稳定性更高,不过对于个人家用,这个稳定性其实意义不大)

下面以aira2的本体程序为例,介绍如何创建一个自定义服务并启用(也就是设置为随系统自动启动)。

  1. 创建并编辑一个我们自己的服务文件 nano /usr/lib/systemd/system/aria2.service 你也可以放到前一个目录里,目前我没有发现两者的分别,仅从字面意义来看,似乎后者这个目录仅对当前用户生效。
  2. 以下用我的代码解释下.service文件的构成:
1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=Aria2 a lightweight multi-protocol & multi-source command-line download utility
After=network.target

[Service]
User=pi
Type=forking
ExecStart=/usr/local/bin/aria2c --conf-path=/home/pi/.aria2/aria2.conf -D
ExecStop=/bin/kill -s STOP $MAINPID
ExecReload=/bin/kill -s HUP $MAINPID

[Install]
WantedBy=multi-user.target

service文件有三个模块,第一个[Unit],里面放一些介绍(会出现在查询进程、服务时的简介中),和启动条件,这里的After=network.target,就是指在网络就绪之后启动这个服务。

第二个模块[Service]是主要模块,这里面包含了服务的用户(User),服务类型(Type),和收到启动信号(ExecStart)、停止信号(ExecStop)、重载信号(ExecReload)之后,该服务要运行的命令。

可以看到,我的代码里,服务启动时的命令(ExecStart),实际上就是运行 /usr/local/bin/aria2c --conf-path=/home/pi/.aria2/aria2.conf -D ,这里有两个地方和前面我们手动运行的时候有所不同:

  1. 多了个 /usr/local/bin —— 因为在服务文件里面编辑的时候,一定要把所有的命令所在的绝对地址填出来,比如aria2c这个程序,我是通过git clone源代码再手动编译得到的,所以我的 aria2c 程序在 /usr/local/bin 这个目录下面,如果大家找不到自己的进程从哪里启动,可以参考linux 查看进程启动路径,一般来说你的进程启动地址,不是cwd对应地址就是exe对应地址,去这两个目录看准没错。
  2. 多了个参数-D,这里就需要结合服务的类型(Type)一起解释——服务的类型定义了你的服务启动方式,总共有如下六种:
    • simple 一个长期运行的进程,这个进程会始终跟随你的shell运行,也就是说如果你的服务type是simple,那么你的shell关闭,这个服务就随之关闭了,这更适合那些一次性运行的命令,比如写入一个日志之类,但不适合我们需要长期运行的 aria2 和 aria2webUI。

    • forking 这个类型的服务,本身只运行一次,但是这类型的服务顾名思义,是应该要fork出一个新的进程的,也就是说,如果你选择这个type,那么你的启动命令(ExecStart)就应该是运行之后会新建一个进程,并且返回一个成功码的,所以如果我们需要用服务启动,就不能单纯的在 ExecStart 后运行一个长期程序,因为这样会导致系统始终无法收到你的服务成功启动的返回码,进而认为你的服务并没有运行成功,于是就会将这个服务终止掉,如果我们的服务中末尾没有 -D ,运行这个服务的结果如下图:

      类型forking的服务,启动命令却没能成功fork出一个进程,导致服务被终止
      好在 aria2c 有一个自带的参数 -D,可以让 aria2c 以daemon的形式运行在后台,于是aria2c --conf-path=/home/pi/.aria2/aria2.conf -D 这条命令,就不再是一个需要长期运行的程序,而是一条fork命令,这就成功的满足了forking type 的 service 的要求,修改之后,成功运行:
      成功fork出

    • oneshot - A short-lived process that is expected to exit.

    • dbus - Like simple, but notification of processes startup finishing is sent over dbus.

    • notify - Like simple, but notification of processes startup finishing is sent over inotify.

    • idle - Like simple, but the binary is started after the job has been dispatched.

(后面四个我也没太看懂😂,似乎和simple类的差不都不太大,需要进一步了解的可以去原帖:Systemd service runs without exiting

5.3-利用crontab和screen,实现需要的程序开机自启(并常驻在后台)

通过自定义服务实现了 aria2 的开机自启之后,我开始研究怎么让web UI也可以开机自启,不幸的是似乎Linux 的 Node 并没有内置启动为 daemon 的参数(也可能是我没找到😂)。

无奈之下我突然想起了万能的screen——顾名思义,这个软件可以让我们在命令行下实现多窗口操作,并且不受 shell 退出的影响,于是综合起来,我就有了如下方案,把 web UI 的 Nodejs 项目的启动(当然是在一个新建的 screen 里面),写到一个 bash 脚本里面,然后通过 Linux 内置的 crontab,就可以自动完成这个脚本的开机启动了。

这就是在前述第 4 节里面的提到过的操作,需要再看一遍的同学可以点击目录快速跳转,因为 1~4 节着重点是给所有像我一样的小白用户准备的,所以我没有使用服务自启动的方案,而是把 aria2 的主体也一起写入了cron自启动。

6-本文所用到的Raspbian(Linux)常见内置命令/第三方工具