本教程重在寻找过程,如果你在意最终结果,请直接看本文最后一段脚本。
  
在几天前,我看到了这篇文章《ac68等arm迅雷、aria2安装小白教程及官固自启动插件教程》[1],标题中的 “官固自启动” 让我非常感兴趣,通过这篇文章我了解到:华硕路由器的 Download Master(下载大师)功能保存在 U 盘上,而华硕官方固件(或 Asuswrt-Merlin)可以运行 U 盘上的脚本,我们也可以将自己的脚本放在 U 盘上实现开机自动运行。
具体是如何实现的?
我向 52asus 的一位管理者 Master 寻求帮助,收到了如下回复

你尝试一下将任意脚本放到/opt/etc/init.d/ 中,并且以 S 开头

相对于 U 盘,是放到了 asusware.arm/etc/init.d/ 目录下
他建议我参考这篇文章《RT-AC66UB1 开机自动执行脚本》[2],这篇文章初期对我的帮助价值非常大,很贴近最终答案,不过由于后面有更好地解决方法,这篇文章不会被用于本教程。
  
于是,我就想到,我之前在 Asuswrt-Merlin 固件时用到的屏蔽广告脚本《AdBlocking with combined hosts file》[3] 能否在我当前官方固件上运行?这个脚本主要是基于修改 hosts 文件实现,官方固件也可以修改 hosts,但是每次开机后 hosts 文件都会被刷新重置 [4],所有保存的信息会被清空。那么我能否利用上方发现的自启动脚本方法,在每次开机清空后再重新写入新的信息到 hosts 文件?答案是可行的。
  
仔细分析《AdBlocking with combined hosts file》文章,我看到了屏蔽广告的 hosts 来源,分别是:
(此处有一个链接无法发出)
http://someonewhocares.org/hosts/zero/hosts
http://pgl.yoyo.org/adservers/se ... &mimetype=plaintext
不过原文中的命令不适用于我,我首先需要做的是:找一个命令把这些链接中的内容写入到路由器的 hosts 中。
  
经过了一番寻找,我找到了这两篇文章《分享一个OpenWRT路由器的自动更新hosts方法,无需脚本》[5] 和《路由器自动修改hosts脚本》[6],这两篇文章都是国人写的,里面命令对我十分有用。
借助《wget 指令用法與教學》[7] 对命令进行了简单的修改,我得到了可以用于路由器更新 hosts 的命令:

  1. wget -q "http://someonewhocares.org/hosts/zero/hosts" "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext" -O /etc/hosts

复制代码

并且将其制作为脚本:

  1. #!/bin/sh
  2. wget -q  "http://someonewhocares.org/hosts/zero/hosts" "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext" -O /etc/hosts

复制代码

命令运行成功,在路由器中 ping 相应网址也得到了正确反馈,但我很快发现,为何我的电脑仍能看到广告?我在电脑中 ping 这些网站发现并没有被屏蔽。于是我开始找原因,在上面那些包含命令的文章中,我注意到了几个关键的命令 service restart_dnsmasq 和 /etc/init.d/dnsmasq restart 这些命令都是用来重启 dnsmasq 的,似乎必须重启后才能对客户端生效,前一个命令重启后会导致 hosts 如同开机般被清空,后者则不适用于华硕路由器。我又重新开始寻找新的命令。
  
在和《RT-AC66UB1 开机自动执行脚本》作者 右手边 交流中,他为我提供了一个新的命令,并发布了一篇教程《如何更改华硕路由器的 hosts》[8],这个新的命令完美地解决了 hosts 修改后不能生效的问题:

  1. killall -SIGHUP dnsmasq

复制代码

既然有了这个命令,那么就把它加入脚本

  1. #!/bin/sh
  2. wget -q "http://someonewhocares.org/hosts/zero/hosts" "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext" -O /etc/hosts
  3. sleep 30
  4. killall -SIGHUP dnsmasq

复制代码

实践证明脚本完美运行。既然可以运行,那么让我来将其改造为开机启动。在本文开头提到的开机启动方法固然可以,但是过于复杂,因为需要基于各种库,如果用不到 Download Master,那些库就没有必要,毕竟那么多的库会拖慢开机时间。
  
因此我开始寻找一个更好地方法,在寻找中我看到了一个新的文章《Hacking Functionality into ASUSWRT Routers》[9] 其中这样写道:

When a USB storage device is inserted into the router’s USB port, the rc system daemon mounts the partition and checks for the existence of an asusware/.asusrouter script on the mount point. If it exists, the asusware folder is then symlinked to /tmp/opt (and also /opt) and the script is executed. Since this is all open source, you can find the relevant code in the mount_partition function in release/src/router/rc/usb.c.

大意为:

当 U 盘插入路由器后,rc 系统守护进程将挂载 U 盘,并检查 U 盘 asusware 文件夹下是否存在名为 .asusrouter 的脚本文件,如果存在将会把 asusware 文件夹链接为 /tmp/opt(和 /opt),并且运行脚本。因为是开源固件,可以在源代码 release/src/router/rc/usb.c 的 mount_partition 函数中找到相关信息。

大家明白了吗?这就是为什么之前脚本要放在 asusware.arm/etc/init.d/ 里面,因为 opt/etc/init.d/ 是启动目录,开机后会运行 /init.d/ 目录下所有的脚本。但是会首先运行 asusware.arm/.asusrouter 这个脚本。

.asusrouter 这个脚本后来了解到主要是用来启动各种库的命令 [10],而我不需要 Download Master 也用不到这些库,直接清空 .asusrouter 文件,将自己的脚本写进去即可。《Hacking Functionality into ASUSWRT Routers》文章中也写道:

Put the commands you wish to execute in asusware/.asusrouter on your USB storage device. Like any shell script, make sure it has #!/bin/sh as its first line and that the file uses UNIX line endings. The filesystem can be anything supported by the kernel – ext2, ext3 or fat. If you are using a filesystem that implements Linux permissions (such as ext2 or ext3), be sure to set the script as executable.

大意为:

将你的命令保存到 U盘 asusware 目录下的 .asusrouter 文件中,和任何 shell 脚本一样,确保脚本第一行内容为 #!/bin/sh,并且以 UNIX 作为换行符,内核支持 ext2、ext3 或 fat 格式的 U 盘,如果使用 Linux 的 ext2 或 ext3 文件系统,请确保脚本拥有执行权限。

他写的这篇文章文件夹目录是不完全正确的,因为 ARM CPU 的路由器文件夹目录是 asusware.arm,一共有四种对应不同架构 CPU 的目录,分别是:asusware、asusware.arm、asusware.big 和 asusware.mipsbig,要确定你的路由器是哪种请在 telnet 下输入命令 [11]:

  1. nvram get apps_install_folder

复制代码

接下来需要注意的是 U 盘不一定是  ext2、ext3 或 fat 格式,经过我的测试 NTFS 和 FAT32 也可以。最重要的是 FAT、FAT32 和 NTFS 这三种格式不需要修改权限,因此我推荐使用这三种格式。
  
继续看《Hacking Functionality into ASUSWRT Routers》文章:

One caveat when running network programs (like DHCP forwarder or mDNS repeater) is that you need to wait until everything has been initialized. ASUS does that by polling the success_start_service NVRAM variable with this bash snippet:

  1. i=0
  2. while [ $i -le 20 ]; do
  3. success_start_service=`nvram get success_start_service`
  4. if [ "$success_start_service" == "1" ]; then
  5. break
  6. fi
  7. i=$(($i+1))
  8. echo "autorun APP: wait $i seconds...";
  9. sleep 1
  10. done

复制代码

大意为

运行和网络有关的脚本,需要等待路由器所有程序初始化完成。因此华硕使用如下命令保证这一点。
这段命令大意是:不断查询程序是否初始化完成,如果没有完成就等待,如果完成了就运行接下来的命令。由于 hosts 是和网络有关的脚本,因此我必须等待所有程序初始化完成。

所以,最终的开机修改 hosts 脚本为:

  1. #!/bin/sh
  2. i=0
  3. while [ $i -le 20 ]; do
  4. success_start_service=`nvram get success_start_service`
  5. if [ "$success_start_service" == "1" ]; then
  6. break
  7. fi
  8. i=$(($i+1))
  9. echo "autorun APP: wait $i seconds...";
  10. sleep 1
  11. done
  12. wget -q  "http://someonewhocares.org/hosts/zero/hosts" "http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext" -O /etc/hosts
  13. sleep 30
  14. killall -SIGHUP dnsmasq

复制代码

将这段脚本保存为 .asusrouter 文件,然后放到 U 盘的 asusware 或者 asusware.arm 或者 asusware.big 或者 asusware.mipsbig 文件夹中,我的路由器则是放到 asusware.arm 目录中。 
好了,这就可以开机运行了

对于你,你也可以将任何 shell 脚本写在 .asusrouter 里面(以 UNIX 作为换行符),并且保存在 U 盘上 asusware 或者 asusware.arm 或者 asusware.big 或者 asusware.mipsbig 文件夹中,具体是哪一个文件夹,上方有查询方法。
我建议 .asusrouter 里面应该至少包含以下内容:

  1. #!/bin/sh
  2. i=0
  3. while [ $i -le 20 ]; do
  4. success_start_service=`nvram get success_start_service`
  5. if [ "$success_start_service" == "1" ]; then
  6. break
  7. fi
  8. i=$(($i+1))
  9. echo "autorun APP: wait $i seconds...";
  10. sleep 1
  11. done
  12. #从下方开始你的脚本

复制代码

如果你有多个脚本,我建议将多个脚本独立保存为随意文件名,然后放入 asusware 或者 asusware.arm 或者 asusware.big 或者 asusware.mipsbig 文件夹中,在 .asusrouter 里面直接写一段代码引导到你的脚本,例如我有名为 test1、test2 和 test3 脚本保存在 U 盘的 asusware.arm 里面,我想要他们几乎同时启动,我需要这样写:

  1. #!/bin/sh
  2. i=0
  3. while [ $i -le 20 ]; do
  4. success_start_service=`nvram get success_start_service`
  5. if [ "$success_start_service" == "1" ]; then
  6. break
  7. fi
  8. i=$(($i+1))
  9. echo "autorun APP: wait $i seconds...";
  10. sleep 1
  11. done
  12. /opt/test1
  13. sleep 1
  14. /opt/test2
  15. sleep 1
  16. /opt/test3

复制代码

如果你不需要同时运行这些脚本,而是上一个脚本运行结束、再运行下一个,你只要将 test1 写在启动命令里面,然后编辑 test1 文件,在最后一行加入 /opt/test2 启动 test2,test2 脚本最后一行加入 /opt/test3 启动 test3,如同多米诺骨牌一样。

特别感谢:
来自 koolshare 的 konglang_616,来自 52asus 的 Master 和 右手边

参考资料:
[1] ac68等arm迅雷、aria2安装小白教程及官固自启动插件教程
[2] RT-AC66UB1 开机自动执行脚本
[3] AdBlocking with combined hosts file(利用 hosts 文件过滤广告 英文)
[4] 請問RT-N16以及N66U的hosts修改
[5] 分享一个OpenWRT路由器的自动更新hosts方法,无需脚本
[6] 路由器自动修改hosts脚本
[7] wget 指令用法與教學
[8] 如何更改华硕路由器的 hosts
[9] Hacking Functionality into ASUSWRT Routers(将脚本运行在华硕路由器上 英文)
[10] 与 @Jack- 讨论开机脚本的问题
[11] 上海电信4K盒子+华硕路由器原厂固件/R7000实现拨号

其他资料:
[12] Asuswrt-Merlin 開機時未執行 init.d 腳本的問題
[13] User scripts · RMerl/asuswrt-merlin Wiki(用户脚本 梅林百科 英文)
[14] ASUSWRT原廠固件安裝 entware

华硕路由器官方固件开机自动运行脚本方法相关推荐

  1. nvidia jetson agx Xavier can 开机自动运行脚本

    测试can的时候一遍遍手动加载特别麻烦,直接写脚本自动加载.记录,备忘. 一.接线图 二.安装依赖 sudo apt install busybox sudo apt install can-util ...

  2. bat脚本如何自动输入y_Linux系统如何设置开机自动运行脚本?

    大家好,我是良许. 在工作中,我们经常有个需求,那就是在系统启动之后,自动启动某个脚本或服务.在 Windows 下,我们有很多方法可以设置开机启动,但在 Linux 系统下我们需要如何操作呢? Li ...

  3. linux开机自动启动开机日志,设置linux开机自动运行脚本

    实现目标:在Linux启动时,自动运行位于普通用户test1根目录下的脚本程序test.py,该程序会在每次执行时自动向本地日志文件追加一条记录,源码如下: from datetime import ...

  4. 基于华硕路由器官方固件搭建个人Web服务器

    华硕路由器,今天我们要分享的干货是基于原厂固件搭建Web服务器,例如:个人博客. 网上有很多教程都是基于第三方固件来现象,并且需要第三方的运行环境,譬如Entware,optware,这里不需要,纯粹 ...

  5. Linux系统如何设置开机自动运行脚本?

    点击上方"五分钟学算法",选择"星标"公众号 重磅干货,第一时间送达 在工作中,我们经常有个需求,那就是在系统启动之后,自动启动某个脚本或服务.在 Window ...

  6. windows开机自动运行脚本

    1. 进入StartUp win7 菜单:开始 - 所有程序 - 启动(右键打开) 会进入目录: C:\Users\Administrator\AppData\Roaming\Microsoft\Wi ...

  7. 用 crontab 实现开机自动运行脚本

    开发「bufpay.com 个人即时到账收款平台」的时候,订单状态和支付二维码的状态如果过期了要实时修改状态,最大效率利用支付二维码. 过期脚本需要开机启动,并且 deamon 运行,有很多办法可以开 ...

  8. Linux之开机自动运行脚本

    0 背景 我们使用ROS开发时,希望当机器人上电以后,会自动启动一些传感器的驱动文件,定位导航,建图所需要的文件,并能按照我们的设定实现一定的功能,比如相应客户端的命令,并按照客户端的指令来动作,或者 ...

  9. rhel7添加开机自动运行脚本

    1.创建脚本并可执行权限 (/my.sh) chmod +x /my.sh 2.打开/etc/rc.d/rc/local文件,在末尾增加如下内容 /my.sh 3.在rhel7中,/etc/rc.d/ ...

最新文章

  1. 微星网卡linux驱动,微星中国
  2. ArcGIS自定义高程
  3. html中内容超出显示省略号的方法
  4. 设计师必备,设计导航网站一流设计导航|16map
  5. 清除浮动(采用BFC)
  6. 带你全面掌握高级知识点!深入理解java虚拟机pdf下载
  7. 虚拟打印机 服务器,PdfFactory(虚拟打印机)
  8. 如何给页面添加背景音乐
  9. python 相对导入与绝对导入
  10. 数据分析软件哪个最好用?
  11. 那些年奋斗的日子,岁月静好
  12. 使用stty修改终端设置 stty 用法!
  13. 设置 app 不能在模拟器上运行
  14. windows之wps卸载不干净解决
  15. Debian搭建DBMS(MariaDB)
  16. h5+js判断网速连接最快的服务器
  17. html5 流星雨,canvas简单流星雨
  18. 云计算、大数据和AI,如同长江后浪推前浪一般涌现区块链
  19. 熵简技术谈 | 熵简科技在资管数据中台的探索与实践
  20. 关于数据库你应该知道的那些事儿

热门文章

  1. 优秀开源音乐项目---落雪音乐软件(免费听歌下载歌曲)
  2. 三维地图代码 echarts demo
  3. Java超详细基础知识
  4. USB复合设备调试 STM32
  5. win7-32位系统,不能运行flash,解决方法。
  6. 02.GCC编译器的使用
  7. 婚庆行业发展报告,2021怎么精准引流?
  8. 四轴平面机器人的手眼标定
  9. 面试被问:你了解的海康威视是一家怎样的公司?
  10. RabbitMQ实现订单超时设计思路、以及在订单过期临界点支付成功如何处理