当前位置: 首页 > news >正文

23 Shell Script服务脚本

Linux 服务脚本

一、Linux 开机自动启动服务

​ linux开机服务原理:

​ ①linux系统启动首先加载kernel

​ ②初始操作系统

​ ③login验证程序等待用户登陆

​ 初始化操作系统

​ kernel加载/sbin/init创建用户空间的第一个程序

​ 该程序完成操作系统的初始化:

​ /etc/inittab文件是/sbin/init程序读取的配置文件

# inittab is no longer used when using systemd.
#
# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target
#
# systemd uses 'targets' instead of runlevels. By default, there are two main targets:
#
# multi-user.target: analogous to runlevel 3
# graphical.target: analogous to runlevel 5
#
# To view current default target, run:
# systemctl get-default
#
# To set a default target, run:
# systemctl set-default TARGET.target
#

​ 0-6,6个级别,每种级别之间的差异其实就是启动脚本的种类数量不同而已

级别含义
0halt(Do NOT set initdefault to this)
1Single user mode
2Multiuser,without NFS (The same as 3, if you do not have networking)
3Full multiuser mode
4unused
5X11
6reboot(Do NOT set initdefault to this)

​ 每个级别对应在/etc/rc.d下都有自己的目录

[root@localhost ~]# ls -l /etc/rc.d
total 4
drwxr-xr-x. 2 root root  70 May 15 23:05 init.d
drwxr-xr-x. 2 root root  45 Nov 16  2020 rc0.d
drwxr-xr-x. 2 root root  45 Nov 16  2020 rc1.d
drwxr-xr-x. 2 root root  45 Nov 16  2020 rc2.d
drwxr-xr-x. 2 root root  45 Nov 16  2020 rc3.d
drwxr-xr-x. 2 root root  45 Nov 16  2020 rc4.d
drwxr-xr-x. 2 root root  45 Nov 16  2020 rc5.d
drwxr-xr-x. 2 root root  45 Nov 16  2020 rc6.d
-rw-r--r--. 1 root root 473 Dec  7  2023 rc.local

​ /etc/rc.d目录:

​ init.d目录是所有的原始服务脚本

​ rc*.d目录中是对init.d目录中脚本的软连接

[root@localhost ~]# ls -l /etc/rc.d/rc3.d
total 0
lrwxrwxrwx. 1 root root 20 Apr 17 04:27 K50netconsole -> ../init.d/netconsole
lrwxrwxrwx. 1 root root 17 Apr 17 04:27 S10network -> ../init.d/network

二、Linux 服务管理操作

​ 不同级别中服务脚本的管理命令

​ chkconfig

​ chkconfig-updates and queries runlevelinformation for system services

​ 服务进程的管理命令

​ service

​ service -run a System V init scrip

chkconfig [--list] [--type type][name]

​ 显示系统服务,以及各个级别开关状态

[root@localhost ~]# chkconfig --listNote: This output shows SysV services only and does not include nativesystemd services. SysV configuration data might be overridden by nativesystemd configuration.If you want to list systemd services use 'systemctl list-unit-files'.To see services enabled on particular target use'systemctl list-dependencies [target]'.netconsole     	0:off	1:off	2:off	3:off	4:off	5:off	6:off
network        	0:off	1:off	2:on	3:on	4:on	5:on	6:off

chkconfig --del name

​ 去除系统启动管理服务中的服务

# 删除服务
[root@localhost ~]# chkconfig --del network# 已经被删除
[root@localhost ~]# chkconfig --list networkNote: This output shows SysV services only and does not include nativesystemd services. SysV configuration data might be overridden by nativesystemd configuration.If you want to list systemd services use 'systemctl list-unit-files'.To see services enabled on particular target use'systemctl list-dependencies [target]'.service network supports chkconfig, but is not referenced in any runlevel (run 'chkconfig --add network')

chkconfig --add name

​ 添加系统服务,且服务脚本要在/etc/rc.d/init.d目录下

# 添加服务
[root@localhost ~]# chkconfig --add network# 查看是否添加
[root@localhost ~]# chkconfig --list networkNote: This output shows SysV services only and does not include nativesystemd services. SysV configuration data might be overridden by nativesystemd configuration.If you want to list systemd services use 'systemctl list-unit-files'.To see services enabled on particular target use'systemctl list-dependencies [target]'.network        	0:off	1:off	2:on	3:on	4:on	5:on	6:off

chkconfig [--level levels] [--type type] name <on|off|reset|resetpriorities>

​ 调整系统启动管理服务中的服务级别

# 将network在启动级别为1设置不启动
[root@localhost ~]# chkconfig --level 1 network on# 查看是否关闭
[root@localhost ~]# chkconfig --listNote: This output shows SysV services only and does not include nativesystemd services. SysV configuration data might be overridden by nativesystemd configuration.If you want to list systemd services use 'systemctl list-unit-files'.To see services enabled on particular target use'systemctl list-dependencies [target]'.netconsole     	0:off	1:off	2:off	3:off	4:off	5:off	6:off
network        	0:off	1:on	2:on	3:on	4:on	5:on	6:off

​ service SCRIPT COMMAND

​ SCRIPT:系统服务脚本名称,在/etc/rc.d/init.d或软连接的目录/etc/init.d目录中

​ COMMAND:脚本不同,但是基本包含{start|stop|status|restart|reload}

​ service --status-all

​ service network restart

# 查看network服务状态
[root@localhost ~]# service network status
Configured devices:
lo ens33
Currently active devices:
lo ens33

​ Linux系统服务脚本:

​ vi /etc/init.d/network

​ 脚本中必须包含以下两行

# chkconfig: 2345 10 90

​ 被注释的,表示调用chkconfig操作add时默认的各级别开启

​ 10:表示启动级别:先启动后关闭,最大值99

​ 90:表示停止级别:先启动后关闭,最大值99

# description: Activates/Deactivates all network interfaces configured to \

# start at boot time.

#! /bin/bash
#
# network       Bring up/down networking
#
# chkconfig: 2345 10 90
# description: Activates/Deactivates all network interfaces configured to \
#              start at boot time.
#
### BEGIN INIT INFO
# Provides: $network
# Should-Start: iptables ip6tables NetworkManager-wait-online NetworkManager $network-pre
# Short-Description: Bring up/down networking
# Description: Bring up/down networking
### END INIT INFO# Source function library.
. /etc/init.d/functions
……

​ 可以看到相应级别目录中的脚本名称前面包含K或S和一个数值

​ K:关闭服务,后面的数值是关闭优先级

​ S:启动服务,后面的数值是启动优先级

[root@localhost ~]# ls -l /etc/rc.d/rc3.d/
total 0
lrwxrwxrwx. 1 root root 20 Apr 17 04:27 K50netconsole -> ../init.d/netconsole
lrwxrwxrwx. 1 root root 17 Oct 16 08:26 S10network -> ../init.d/network

三、tomcat服务脚本

​ 安装java

# 下载java1.8
[root@localhost ~]# yum -y install java-1.8.0*# 验证是否安装成功
[root@localhost ~]# java -version
openjdk version "1.8.0_412"
OpenJDK Runtime Environment (build 1.8.0_412-b08)
OpenJDK 64-Bit Server VM (build 25.412-b08, mixed mode)

​ bash以交互方式启动时会加载/etc/profile文件,所以在这里定义的环境变量能被用户交互时用到,用户交互启动程序所依赖•

​ 但是系统服务脚本优先在用户登陆前启动,且不会读取/etc/profile

# 下载tomcat9.0
[root@localhost ~]# wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.96/bin/apache-tomcat-9.0.96.tar.gz# 解压文件
[root@localhost ~]# tar -xzvf apache-tomcat-9.0.96.tar.gz # 进入tomcat/bin
[root@localhost ~]# cd apache-tomcat-9.0.96/bin# 启动服务
[root@localhost bin]# ./startup.sh
Using CATALINA_BASE:   /root/apache-tomcat-9.0.96
Using CATALINA_HOME:   /root/apache-tomcat-9.0.96
Using CATALINA_TMPDIR: /root/apache-tomcat-9.0.96/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /root/apache-tomcat-9.0.96/bin/bootstrap.jar:/root/apache-tomcat-9.0.96/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.# 查看运行进程
[root@localhost bin]# ps -ef | grep java
root       1648      1 25 11:07 pts/0    00:00:03 /usr/bin/java -Djava.util.logging.config.file=/root/apache-tomcat-9.0.96/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /root/apache-tomcat-9.0.96/bin/bootstrap.jar:/root/apache-tomcat-9.0.96/bin/tomcat-juli.jar -Dcatalina.base=/root/apache-tomcat-9.0.96 -Dcatalina.home=/root/apache-tomcat-9.0.96 -Djava.io.tmpdir=/root/apache-tomcat-9.0.96/temp org.apache.catalina.startup.Bootstrap start
root       1676   1371  0 11:08 pts/0    00:00:00 grep --color=auto java# 关闭防火墙
[root@localhost bin]# systemctl stop firewalld
[root@localhost bin]# setenforce 0# 浏览器访问http://your_ip:8080# 停止服务
[root@localhost bin]# ./shutdown.sh

​ 但是这种运行方式需要用户干预,我们更希望的是服务器启动后能将tomcat作为系统服务启动

​ 我们自己实现一个tomcat的系统服务脚本

​ 对于service调取脚本可以传递给脚本的参数应该包含:

​ start

​ stop

​ restart

​ status

​ 作为服务脚本必须实现的内容:

# chkconfig: 123456 2079

# description: This is a Tomcat Server shell scripts

​ 另外,系统还有一个通用的工具脚本,其中包含了一些方便我们服务脚本开发的函数

. /etc/rc.d/init.d/functions

# 创建tomcat
[root@localhost bin]# touch /etc/init.d/tomcat# 添加执行权
[root@localhost bin]# chmod +x /etc/init.d/tomcat[root@localhost bin]# vi /etc/init.d/tomcat
#!/bin/bash
#
# chkconfig: 123456 2079
# description: This is a Tomcat Server shell scripts
. /etc/rc.d/init.d/functions

etc/rc.d/init.d/functions脚本介绍:

​ functions这个脚本是给/etc/init.d里边的文件使用的,提供了一些基础的功能

​ 重要函数:

​ checkpid:检查是否已存在pid,如果有一个存在,返回0(通过查看/proc目录)

​ daemon:启动某个服务。/etc/init.d目录部分脚本的start使用到这个

​ killproc:杀死某个进程。/etc/init.d目录部分脚本的stop使用到这个

​ status:返回一个服务的状态

​ 我们可以在自己的脚本中通过source或.的方式导入

​ tomcat有自己的服务管理脚本

​ 在系统服务脚本中判断服务进程状态

​ 最直接的方式是用进程的PID

​ 观察:bin/startup.sh

​ 发现最终调用catalina.sh脚本

​ 并传参start

​ 所以查找catalina.sh

​ 查找到这行:

elif [ "$1" = "start" ] ; then

​ 向下寻找到分支结束前,添加:

echo "CATALINA_PID:$!

# 打印pid
[root@localhost bin]# vi startup.sh
# 第519行,添加
echo "CATALINA_PID:$!"# 返回编写tomcat
[root@localhost bin]# vi /etc/init.d/tomcat
#!/bin/bash
#
# chkconfig: 123456 2079
# description: This is a Tomcat Server shell scripts
. /etc/rc.d/init.d/functions
tom_home=/root/apache-tomcat-9.0.96/bin
# tomcat启动后将进程ID存在这个文件中
tom_lock_file=/var/lock/subsys/tom.lock
tom_status(){if [ -f $tom_lock_file ]; thenlock_pid=`cat $tom_lock_file`if [ ! -z $lock_pid ];then# 调用函数来检测PID对应的进程是否存在if checkpid `cat $tom_lock_file`; thenecho "tomcat is running( $lock_pid )..." && return 0elseecho "tomcat ( $lock_pid )is not running but lock_fileexist" && return 1fififiecho "tomcat is not running ......"  && return 2
}
tom_start(){if ! tom_status >& /dev/null ; then# 这里启动tomcat,并获取pid存到锁文件中$tom_home/startup.sh |& grep "CATALINA_PID:" | sed 's/CATALINA_PID:\(.*\)/\1/' > $tom_lock_fileecho "tomcat started ..."fitom_status
}
tom_stop(){tom_status$tom_home/shutdown.sh >& /dev/nullecho "tomcat stoped..."echo '' > $tom_lock_file
}
tom_restart()
{tom_stopsleep 1tom_start
}
case $1 instatus)tom_status;;start)tom_start;;stop)tom_stop;;restart)tom_restart;;*)echo $"Usage: $0 {start|stop|status|restart}";;
esac

​ 设置开机自启动

[root@localhost bin]# chkconfig --level 3 tomcat on

相关文章:

23 Shell Script服务脚本

Linux 服务脚本 一、Linux 开机自动启动服务 ​ linux开机服务原理&#xff1a; ​ ①linux系统启动首先加载kernel ​ ②初始操作系统 ​ ③login验证程序等待用户登陆 ​ 初始化操作系统 ​ kernel加载/sbin/init创建用户空间的第一个程序 ​ 该程序完成操作系统的初…...

三周精通FastAPI:3 查询参数

查询参数 FastAPI官网手册&#xff1a;https://fastapi.tiangolo.com/zh/tutorial/query-params/ 上节内容&#xff1a;https://skywalk.blog.csdn.net/article/details/143046422 声明的参数不是路径参数时&#xff0c;路径操作函数会把该参数自动解释为**查询**参数。 from…...

大语言模型学习指南:入门、应用与深入

0x00 学习路径概述 本文将学习路径划分为三个部分&#xff1a;入门篇、应用篇、深入篇。每个章节针对不同的学习需求&#xff0c;帮助你从基础知识入手&#xff0c;逐步掌握大语言模型&#xff08;LLM&#xff09;的使用、应用开发以及技术原理等内容。 学习目标 入门篇&…...

【Linux-进程间通信】匿名管道+4种情况+5种特征

匿名管道 匿名管道&#xff08;Anonymous Pipes&#xff09;是Unix和类Unix操作系统中的一种通信机制&#xff0c;用于在两个进程之间传递数据。匿名管道通常用于命令行工具之间的数据传递&#xff1b; 匿名管道的工作原理是创建一个临时文件&#xff0c;该文件被称为管道文件…...

Perl打印9x9乘法口诀

本章教程主要介绍如何用Perl打印9x9乘法口诀。 一、程序代码 1、写法① use strict; # 启用严格模式&#xff0c;帮助捕捉变量声明等错误 use warnings; # 启用警告&#xff0c;帮助发现潜在问题# 遍历 1 到 9 的数字 for my $i (1..9) {# 对于每个 $i&#xff0c;遍历 1…...

Android--第一个android程序

写在前边 ※安卓开发工具常用模拟器汇总Android开发者必备工具-常见Android模拟器(MuMu、夜神、蓝叠、逍遥、雷电、Genymotion...)_安卓模拟器-CSDN博客 ※一般游戏模拟器运行速度相对较快&#xff0c;本文选择逍遥模拟器_以下是Android Studio连接模拟器实现(先从以上博文中…...

MySQL的并行复制原理

1. 并行复制的概念 并行复制&#xff08;Parallel Replication&#xff09;是一种通过同时处理多个复制任务来加速数据复制的技术。它与并发复制的区别在于&#xff0c;并行复制更多关注的是数据块或事务之间的并行执行&#xff0c;而不是单纯的任务并发。在数据库主从复制中&…...

2023年五一杯数学建模C题双碳目标下低碳建筑研究求解全过程论文及程序

2023年五一杯数学建模 C题 双碳目标下低碳建筑研究 原题再现&#xff1a; “双碳”即碳达峰与碳中和的简称&#xff0c;我国力争2030年前实现碳达峰&#xff0c;2060年前实现碳中和。“双碳”战略倡导绿色、环保、低碳的生活方式。我国加快降低碳排放步伐&#xff0c;大力推进…...

信息安全工程师(57)网络安全漏洞扫描技术与应用

一、网络安全漏洞扫描技术概述 网络安全漏洞扫描技术是一种可以自动检测计算机系统和网络设备中存在的漏洞和弱点的技术。它通过使用特定的方法和工具&#xff0c;模拟攻击者的攻击方式&#xff0c;从而检测存在的漏洞和弱点。这种技术可以帮助组织及时发现并修补漏洞&#xff…...

练习题 - Scrapy爬虫框架 Spider Middleware 爬虫页中间件

在 web 爬虫开发中,Scrapy 是一个非常强大且灵活的框架,它可以帮助开发者轻松地从网页中提取数据。Scrapy 的下载器中间件(Downloader Middleware)是 Scrapy 处理下载请求和响应的一个重要组件。通过使用和编写下载器中间件,开发者可以自定义请求的处理过程,增加请求头信…...

探索C++的工具箱:双向链表容器类list(1)

引言 在C中&#xff0c;std::list 是一个标准库提供的容器类&#xff0c;属于C STL&#xff08;标准模板库&#xff09;。std::list 是一种独特而强大的容器&#xff0c;它使用双向链表结构来管理元素。无论是在处理动态数据集合&#xff0c;还是在需要频繁进行插入和删除操作时…...

大厂高频算法考点--单调栈

什么是单调栈&#xff1a; 单调栈就是借助一个栈&#xff0c;在仅仅使用当前栈的条件下&#xff0c;时间复杂度是N&#xff08;n&#xff09;,将每个节点最有离这他最近的大于或者是小于的数据返回&#xff0c;将已知数组的元素放到栈里。再自我实现的代码里面我们使用数组实现…...

Unity使用Git及GitHub进行项目管理

git: 工作区,暂存区(存放临时要存放的内容),代码仓库区1.初始化 git init 此时展开隐藏项目,会出现.git文件夹 2.减小项目体积 touch .gitignore命令 创建.gitignore文件夹 gitignore文件夹的内容 gitignore中添加一下内容 # This .gitignore file should be place…...

如何将本地 Node.js 服务部署到宝塔面板:完整的部署指南

文章简介&#xff1a; 将本地开发的 Node.js 项目部署到线上服务器是开发者常见的工作流程之一。在这篇文章中&#xff0c;我将详细介绍如何将本地的 Node.js 服务通过宝塔面板&#xff08;BT 面板&#xff09;上线。宝塔面板是一个强大的服务器管理工具&#xff0c;具有简洁的…...

SpringBoot项目启动报错:命令行太长解决

文章目录 SpringBoot项目启动报错&#xff1a;命令行太长解决1. 第一种方法1. 第二种方法1-1 旧版本Idea1-2 新版本Idea 3. 重新启动SpringBoot项目即可解决 SpringBoot项目启动报错&#xff1a;命令行太长解决 报错信息&#xff1a; 1. 第一种方法 1. 第二种方法 找到项目…...

使用Docker启动的Redis容器使用的配置文件路径等问题以及Python使用clickhouse_driver操作clickhouse数据库

一、使用Docker启动的Redis容器使用的配置文件路径等问题 1.docker启动的redis使用的配置文件路径是什么 使用docker搭建redis服务&#xff0c;本身redis启动的时候可以指定配置文件的&#xff0c; redis-server /指定配置文件路径/redis.conf。 但手上也没有一个redis配置文件…...

硬盘格式化后能恢复数据吗?4款好用的数据恢复软件,格式化后也能安心

咱们今天来谈谈一个挺烦人的问题——硬盘格式化后能恢复数据吗&#xff1f;别担心&#xff0c;能的&#xff01;只要你用对方法&#xff0c;就算硬盘被清空了&#xff0c;那些重要文件还是能找回来的。下面&#xff0c;我就给你们介绍几款超给力的数据恢复软件&#xff0c;让你…...

【选择C++游戏开发技术】

在选择C游戏开发技术时&#xff0c;以下几个因素是需要考虑的&#xff1a; 1. 游戏类型&#xff1a;不同类型的游戏可能需要不同的技术。例如&#xff0c;2D游戏通常采用基于精灵的引擎&#xff0c;而3D游戏通常采用基于物理模拟的引擎。根据游戏类型选择适合的技术是很重要的…...

Oracle数据库系统表空间过大,清理SYSTEM、SYSAUX表空间

一.前言 在oracle数据库中&#xff0c;system为系统表空间&#xff0c;存放着一些我们经常用到的系统表和视图&#xff0c;sysaux为辅助表空间&#xff0c;辅助着系统表空间。这两个表空间不宜添加数据文件&#xff0c;会使系统表空间过于臃肿&#xff0c;从而影响数据库的使用…...

LaTeX参考文献工具和宏包bibmap项目简介

LaTeX参考文献工具和宏包bibmap项目简介 LaTeX 中的参考文献生成方式主要有三种&#xff1a;第一种是手动写thebibliography环境的&#xff0c;第二种事基于bibtex程序的&#xff0c;第三种则是基于biblatex宏包和biber程序的。本文介绍的bibmap项目则提供了第四种方法。目前b…...

MATLAB App Designer打包实战:从GUI到独立安装包的完整部署指南

1. MATLAB App Designer打包前的准备工作 第一次把MATLAB开发的GUI程序打包成独立安装包时&#xff0c;我踩了不少坑。记得当时给合作方演示算法&#xff0c;对方电脑没有MATLAB环境&#xff0c;只能干着急。后来花了三天时间才搞明白整个打包流程&#xff0c;现在把这些经验系…...

SiameseAOE模型Dify平台插件开发:低代码构建智能文本分析工作流

SiameseAOE模型Dify平台插件开发&#xff1a;低代码构建智能文本分析工作流 1. 引言 你有没有遇到过这样的场景&#xff1f;客服团队每天要处理海量的用户反馈&#xff0c;市场部门需要从成千上万的评论里提炼产品卖点&#xff0c;内容审核人员得盯着屏幕&#xff0c;手动标记…...

3分钟掌握RePKG:Wallpaper Engine资源提取与转换全攻略

3分钟掌握RePKG&#xff1a;Wallpaper Engine资源提取与转换全攻略 【免费下载链接】repkg Wallpaper engine PKG extractor/TEX to image converter 项目地址: https://gitcode.com/gh_mirrors/re/repkg RePKG是一款专为Wallpaper Engine设计的强大资源提取工具&#x…...

Kubernetes网络入门004篇【20260407】

文章目录 Kubernetes 网络入门完整版(深度扩容侧重基础知识) 一、学习K8s网络前必须掌握的Linux网络基础 1.1 Linux Network Namespace(网络命名空间) 1.2 Veth Pair(虚拟以太网设备对) 1.3 Linux Bridge(Linux网桥) 1.4 iptables 1.5 路由表 二、K8s网络基础核心概念与…...

PX4+Gazebo仿真:从键盘指令到无人机轨迹的Offboard控制实践

1. 环境搭建与基础配置 在开始PX4Gazebo仿真之前&#xff0c;我们需要先搭建好开发环境。我推荐使用Ubuntu 20.04 LTS系统&#xff0c;这是目前最稳定的ROS Noetic支持版本。记得第一次配置环境时&#xff0c;我花了整整一天时间解决各种依赖问题&#xff0c;现在把这些经验都总…...

3大维度解锁BG3 Mod Manager潜能:构建高效博德之门3模组管理体系

3大维度解锁BG3 Mod Manager潜能&#xff1a;构建高效博德之门3模组管理体系 【免费下载链接】BG3ModManager A mod manager for Baldurs Gate 3. This is the only official source! 项目地址: https://gitcode.com/gh_mirrors/bg/BG3ModManager 价值定位&#xff1a;重…...

电源噪声克星:手把手教你用陷波滤波器消除60Hz工频干扰(Matlab/示波器实测)

电源噪声克星&#xff1a;手把手教你用陷波滤波器消除60Hz工频干扰&#xff08;Matlab/示波器实测&#xff09; 当你的高精度ADC采集数据出现周期性波动时&#xff0c;很可能是工频干扰在作祟。这种以60Hz&#xff08;或50Hz&#xff09;为基频的噪声&#xff0c;就像电子系统中…...

终极Goyo.vim配置指南:打造完美无干扰写作环境的10个技巧

终极Goyo.vim配置指南&#xff1a;打造完美无干扰写作环境的10个技巧 【免费下载链接】goyo.vim :tulip: Distraction-free writing in Vim 项目地址: https://gitcode.com/gh_mirrors/go/goyo.vim Goyo.vim是一款专为Vim用户设计的无干扰写作插件&#xff0c;它能帮助你…...

Grimoire:终极书签管理器 - 为巫师打造的神奇知识宝库

Grimoire&#xff1a;终极书签管理器 - 为巫师打造的神奇知识宝库 【免费下载链接】grimoire Bookmark manager for the wizards &#x1f9d9; 项目地址: https://gitcode.com/gh_mirrors/gr/grimoire Grimoire 是一款专为现代互联网巫师设计的终极书签管理器&#xff…...

BilibiliDown:3分钟上手,从此告别B站视频下载烦恼

BilibiliDown&#xff1a;3分钟上手&#xff0c;从此告别B站视频下载烦恼 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_mi…...