直链不用愁,gist 来搞定

直链不用愁,gist 来搞定

直链(Direct Link)是指一个直接指向特定文件或资源的 URL 链接,用户点击后可以直接访问或下载该文件,而无需经过中间页面或登录等步骤。

直链的特点

  1. 直接访问:点击后立即跳转到目标文件或资源。
  2. 无需中转:不经过广告、登录等额外页面。
  3. 快速下载:常用于大文件的快速下载。

直链示例

正确的直链

  1. https://tgfile.yuzong.nyc.mn/1739350116061.jpg 是一个直链,点击会直接打开一张图片或直接下载一张图片
  2. https://raw.githubusercontent.com/yutian81/IP-SpeedTest/refs/heads/master/README.md 这也是一个直链,点击会直接打开文档内容或下载文档

github 或 gitee 平台的公开仓库都可以生成文件直链,以 github 为例,打开任意一个文件,点击右上角的 raw 就可以生成一个直链

image.png

github 的直链都是这样以 https://raw.githubusercontent.com 开头的链接,例如:

1
https://raw.githubusercontent.com/yutian81/greasyfork-js/refs/heads/main/youtube-adb.js

错误的直链

  1. https://www.lanzoum.com/i2zSt2riwzmh 这不是直链,访问这个网页不能直接下载
  2. https://www.123pan.com/s/A6cA-7opJh 这也不是直链

Github 直链的限制

github 或 gitee 只能为公开仓库内的文件生成直链,那我们有些文件是私密的,无法作为 API 拉取,也不宜对外分享,只能放在私库,怎么生成直链呢?

方法一:通过 Cf worker 项目搭建私库直链

这个方法详见 cm 的 私库直链项目 以及他的博文教程,这里不详叙。今天主要讲方法二。

方法二:通过 Github gist 私有代码生成直链

Gist 入口

打开 github 主页,点击右上角 你的头像your gists 或者 点此 直接进入

创建一个私有 gist

image.png

生成 gist 直链

进入你创建的私有 gist,点击右上角 Raw,会打开一个网页

image.png

网页地址类似这样:
https://gist.githubusercontent.com/yutian81/591abcdefg9a2201334414588e/raw/7abcdefg9c21cb12345677f6b8711babcdef955a/domains.json

这还不是直链,这个链接只有你自己能访问

将上面链接中 raw文件名 之间的一长串字符删除,得到一个类似这样的地址:
https://gist.githubusercontent.com/yutian81/591abcdefg9a2201334414588e/raw/domains.json

这就是我们需要的直链

短链接缩短直链

得到的 gist 直链会很长,有些有强迫症的朋友可能会非常不爽,没关系,通过短链接服务或者缩短链接

这是我的 短链服务 地址,将上面得到的直链输入进去,可以得到一个类似这样的短链 https://slink.yuzong.nyc.mn/W2G7F5

如何使用直链

在需要拉取直链内容的场景下输入直链地址,比如 cm edt 项目的 ADDAPIADDCSV 变量,比如我的 域名监控项目 需要用到的 DOMAINS 变量

其他可以生成直链的平台

除了 github 以外,还有 Gitee 可以生成直链,入口地址;如果你有自己的 vps,也可以通过 vps 搭建文件分享服务来生成直链;另外,CF 的 r2 和 backblaze 的 S3 也可以生成直链

自动化上传到 gist 并获取直链

  • 前提:安装 windows 版 gitbash、jq 并配置好系统环境变量(如果不懂可以谷歌搜索或问 AI)
  • 创建一个 shell 脚本,命名为 upload_to_gist.sh,内容如下:
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/bin/bash

# 配置信息
GIST_TOKEN="你的github token"
GIST_ID="" # 留空会自动生成。如果要覆盖gist上的旧文件,填入之前运行本脚本生成的id

# 颜色和符号定义
RED='\033[1;31m' # 错误/警告
GREEN='\033[1;32m' # 成功
YELLOW='\033[1;33m' # 提示
CYAN='\033[1;36m' # 标题/链接
BLUE='\033[1;34m' # 步骤
NC='\033[0m' # 颜色重置

CHECK="${GREEN}${NC}"
CROSS="${RED}${NC}"
ARROW="${CYAN}${NC}"
DOT="${YELLOW}${NC}"

show_help() {
echo -e "${CYAN}用法:${NC} $0 [文件1] [文件2]..."
echo -e "${YELLOW}示例:${NC}"
echo -e " $0 file.txt ${CYAN}# 自动创建新Gist${NC}"
echo -e " GIST_ID=xxx $0 file ${CYAN}# 更新现有Gist${NC}"
}

print_step() { echo -e "${DOT} ${BLUE}$1...${NC}"; }
print_success() { echo -e "${CHECK} ${GREEN}$1${NC}"; }
print_error() { echo -e "${CROSS} ${RED}错误: $1${NC}" >&2; }

convert_path() {
local win_path="$1"
win_path=$(echo "$win_path" | sed 's/ /_/g') # 替换路径中的中文空格问题
if command -v cygpath &> /dev/null; then
cygpath -u "$win_path" 2>/dev/null || echo "$win_path"
else
echo "$win_path" | sed 's|\\|/|g; s|^$$[A-Za-z]$$:|/\1|'
fi
}

# 检测文件编码
detect_encoding() {
local encoding=$(file -b --mime-encoding "$1")
echo -e "${YELLOW}调试: 文件 $1 检测到编码 -> $encoding${NC}" >&2
case $encoding in
"utf-8") echo "UTF-8" ;;
"iso-8859-1" | "cp936") echo "GBK" ;;
"utf-16le") echo "UTF-16" ;;
"unknown-8bit") echo "GB18030" ;;
"binary") echo "BASE64" ;;
*) echo "$encoding" ;;
esac | tr 'A-Z' 'a-z'
}

# 转换文件编码
process_content() {
local detected_encoding=$(detect_encoding "$1")
local content

# 二进制文件特殊处理
if [ "$detected_encoding" = "base64" ]; then
print_error "不支持二进制文件: $1"
exit 1
fi

# 智能编码转换(包含UTF-8验证)
if [ "$detected_encoding" = "utf-8" ]; then
# 原始UTF-8内容处理
content=$(sed '
s/\r$//;
1s/^\xEF\xBB\xBF//;
s/[\x00-\x09\x0B-\x1F\x7F]//g;
' "$1")
else
# 中文编码转换流程
content=$(iconv -f "$detected_encoding" -t UTF-8//TRANSLIT "$1" 2>/dev/null ||
iconv -f GBK -t UTF-8//TRANSLIT "$1" 2>/dev/null ||
iconv -f GB18030 -t UTF-8//TRANSLIT "$1")
fi

# 最终编码验证
if ! echo "$content" | iconv -t UTF-8 -c &>/dev/null; then
print_error "文件包含无效字符: $1"
exit 1
fi
echo "$content"
}

# 主程序
[ $# -eq 0 ] && { show_help; exit 1; }

declare -A file_data
for file in "$@"; do
print_step "处理文件 $file"
resolved_file=$(convert_path "$file")

# 文件验证
if [ ! -f "$resolved_file" ]; then
print_error "文件不存在: $resolved_file"
exit 1
fi

filename=$(basename "$resolved_file")
content=$(process_content "$resolved_file")

# 内容验证
if [ -z "$content" ]; then
print_error "文件内容为空: $filename"
exit 1
fi

file_data["$filename"]="$content"
print_success "已加载 $filename (${#content} 字符)"
done

build_json() {
jq -n --argjson files "$(
jq -n --argjson data "$(
for key in "${!file_data[@]}"; do
jq -n --arg k "$key" --arg c "${file_data[$key]}" \
'{($k): {content: $c}}'
done | jq -s 'add'
)" '$data'
)" '{public: false, files: $files}'
}

# API交互
print_step "准备API请求"
if [ -z "$GIST_ID" ]; then
method="POST"
endpoint="https://api.github.com/gists"
else
method="PATCH"
endpoint="https://api.github.com/gists/$GIST_ID"
fi

# 调试文件处理
DEBUG_JSON=".gist_debug.json"
build_json | jq . > "$DEBUG_JSON"

print_step "发送请求到GitHub"
response=$(curl -s -X "$method" \
-H "Authorization: token $GIST_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-H "Content-Type: application/json; charset=utf-8" \
-d @"$DEBUG_JSON" \
"$endpoint")

# 清理调试文件
rm -f "$DEBUG_JSON"

# 错误处理
if echo "$response" | grep -q '"message":'; then
error_msg=$(echo "$response" | jq -r '.message')
print_error "API请求失败: $error_msg"
exit 1
fi

# 获取版本信息
GIST_ID=$(echo "$response" | jq -r '.id')
print_step "获取最新版本哈希"
COMMIT_HASH=$(curl -s -H "Authorization: token $GIST_TOKEN" \
"https://api.github.com/gists/$GIST_ID" | jq -r '.history[0].version')

# 显示结果
echo -e "\n${CYAN}══════════════ Gist 信息 ══════════════${NC}"
echo -e "${YELLOW}唯一标识:${NC} $GIST_ID"
echo -e "${YELLOW}管理界面:${NC} https://gist.github.com/$GIST_ID"

for filename in "${!file_data[@]}"; do
echo -e "\n${ARROW} ${YELLOW}文件:${NC} ${CYAN}$filename${NC}"
echo -e " ${GREEN}私有直链:${NC} https://gist.githubusercontent.com/raw/$GIST_ID/$COMMIT_HASH/$filename"
echo -e " ${BLUE}公开直链:${NC} https://gist.githubusercontent.com/raw/$GIST_ID/$filename"
done
echo -e "${CYAN}═══════════════════════════════════════${NC}"

win 下打开 gitbash,执行 bash upload_to_gist.sh "E:\vscode\gist直链\text.txt",将自动上传 text.txt 文件并输出 gist id 和直链地址

  • 使用更简单的 bat 一键运行方式

使用 bat 一键运行,将要上传的脚本拖放到 bat 上 即可。在 upload_to_gist.sh 同级目录 创建一个 run.bat,内容如下:

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
@echo off
chcp 65001 > nul
setlocal enabledelayedexpansion

:: 配置环境路径(根据实际安装路径修改)
set "BASH_CMD=D:\Program Files\Git\bin\bash.exe"
set "SCRIPT_PATH=%~dp0upload_to_gist.sh"

:: 检查Bash是否存在
if not exist "%BASH_CMD%" (
echo 错误:未找到Git Bash,请确保已安装Git for Windows。
pause
exit /b 1
)

:: 检查脚本是否存在
if not exist "%SCRIPT_PATH%" (
echo 错误:未找到脚本文件 %SCRIPT_PATH%
pause
exit /b 1
)

:: 增强路径处理
set "args="
for %%a in (%*) do (
set "win_path=%%~a"
set "win_path=!win_path:'=''!" # 处理单引号问题

:: 使用更安全的路径转换方式
"%BASH_CMD%" -c "cygpath -u '!win_path!'" > temp_path.txt
set /p unix_path=<temp_path.txt
del temp_path.txt

set "args=!args! '!unix_path!'"
)

:: 执行脚本并捕获错误
"%BASH_CMD%" -lc "'%SCRIPT_PATH%' !args!"
set "exit_code=!errorlevel!"

:: 错误处理
if !exit_code! neq 0 (
echo.
echo 错误:脚本执行失败 (代码 !exit_code!)
pause
)

endlocal
exit /b !exit_code!

#github #同步 #API