Skip to content

Commit ca95b51

Browse files
committed
perf(scripts): 节点扫描改单次 awk,消除循环内 fork
- nodes.sh: scan_nodes_in_dir 由每文件两次 fork (sed+basename) 改为每目录单次 awk 直接产出 TSV,N 节点从 2N fork 降至 1 fork - nodes.sh: 移除只写不读的 NODE_SCAN_* 计数器与 append_node_record - subscription.sh/cli/nodes.sh: 循环与展示路径的 basename 改用参数展开 ${x##*/},去除每次调用的子进程 - 经夹具对拍,扫描输出与原实现逐字节一致
1 parent 22b9fe3 commit ca95b51

3 files changed

Lines changed: 36 additions & 66 deletions

File tree

src/module/scripts/cli

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ cmd_service_status() {
262262
udp_port="$(read_conf "$TPROXY_CONF" "PROXY_UDP_PORT" "-")"
263263
dns_port="$(read_conf "$TPROXY_CONF" "DNS_PORT" "-")"
264264

265-
[ -n "$current" ] && printf "当前节点: %s\n" "$(basename "$current")"
265+
[ -n "$current" ] && printf "当前节点: %s\n" "${current##*/}"
266266
printf "出站模式: %s\n" "$mode"
267267
printf "透明代理端口: TCP=%s UDP=%s DNS=%s\n" "$tcp_port" "$udp_port" "$dns_port"
268268

@@ -375,7 +375,7 @@ cmd_node_current() {
375375
tag="$(detect_outbound_tag "$current" || true)"
376376

377377
section "当前节点"
378-
printf "文件名: %s\n" "$(basename "$current")"
378+
printf "文件名: %s\n" "${current##*/}"
379379
[ -n "$tag" ] && printf "标签: %s\n" "$tag"
380380
printf "路径: %s\n" "$current"
381381
}
@@ -388,7 +388,7 @@ cmd_node_use() {
388388
[ -n "$query" ] || die_cli "用法: cli node use <名称|标签|路径>"
389389
prepare_node_scan
390390
node="$(resolve_node_from_scan "$CLI_NODE_SCAN_FILE" "$query")"
391-
info "正在切换节点: $(basename "$node")"
391+
info "正在切换节点: ${node##*/}"
392392
sh "$SWITCH_SCRIPT" config "$node"
393393
}
394394

@@ -455,7 +455,7 @@ cmd_node_remove() {
455455
# 禁止删除正在使用的节点
456456
[ "$node" != "$current" ] || die_cli "不能删除当前正在使用的节点"
457457
rm -f "$node"
458-
info "已删除节点: $(basename "$node")"
458+
info "已删除节点: ${node##*/}"
459459
}
460460

461461
#######################################

src/module/scripts/core/subscription.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ update_all_subscriptions() {
378378
name="$(read_subscription_meta_value "$meta_file" "name" || true)"
379379
url="$(read_subscription_meta_value "$meta_file" "url" || true)"
380380
[ -n "$url" ] || continue
381-
[ -n "$name" ] || name="$(basename "$sub_dir")"
381+
[ -n "$name" ] || name="${sub_dir##*/}"
382382

383383
# 命令行参数优先,否则使用各订阅各自的持久化值
384384
saved_ua="$(read_subscription_meta_value "$meta_file" "ua" || true)"
@@ -430,7 +430,7 @@ list_subscriptions() {
430430

431431
name="$(read_subscription_meta_value "$meta_file" "name" || true)"
432432
updated="$(read_subscription_meta_value "$meta_file" "updated" || true)"
433-
[ -n "$name" ] || name="$(basename "$sub_dir")"
433+
[ -n "$name" ] || name="${sub_dir##*/}"
434434

435435
# 统计该订阅下的有效节点数
436436
node_count=0

src/module/scripts/utils/nodes.sh

Lines changed: 30 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
#######################################
99

1010
readonly NODE_RECORD_DELIM="$(printf '\t')" # 扫描记录的字段分隔符 (制表符)
11-
NODE_SCAN_VALID_COUNT=0 # 最近一次扫描的有效节点数
12-
NODE_SCAN_SKIPPED_COUNT=0 # 最近一次扫描跳过的文件数
1311

1412
#######################################
1513
# 判断文件是否为节点配置文件
@@ -147,81 +145,54 @@ subscription_display_name() {
147145
if [ -n "$name" ]; then
148146
printf "%s\n" "$name"
149147
else
150-
printf "%s\n" "$(basename "$sub_dir")"
148+
# 回退为目录名 (参数展开取末段,等价 basename)
149+
printf "%s\n" "${sub_dir##*/}"
151150
fi
152151
}
153152

154-
#######################################
155-
# 重置节点扫描计数器
156-
# 参数: 无
157-
# 返回: 无
158-
#######################################
159-
reset_node_scan_counters() {
160-
NODE_SCAN_VALID_COUNT=0
161-
NODE_SCAN_SKIPPED_COUNT=0
162-
}
163-
164-
#######################################
165-
# 向扫描结果文件追加一条节点记录
166-
# 参数:
167-
# $1 输出文件
168-
# $2 节点文件路径
169-
# $3 出站标签
170-
# $4 来源 (默认节点 / 订阅名)
171-
# $5 是否当前节点 (1=是)
172-
# 返回: 无 (追加一行 制表符分隔 记录)
173-
#######################################
174-
append_node_record() {
175-
local output_file="$1"
176-
local file="$2"
177-
local tag="$3"
178-
local source="$4"
179-
local is_current="$5"
180-
181-
printf "%s\t%s\t%s\t%s\t%s\n" "$file" "$(basename "$file")" "$tag" "$source" "$is_current" >> "$output_file"
182-
}
183-
184153
#######################################
185154
# 扫描单个目录中的节点并写入结果文件
155+
# 单次 awk 遍历目录内全部节点文件,逐行输出
156+
# "路径 文件名 标签 来源 是否当前" (制表符分隔)。
186157
# 参数:
187158
# $1 节点目录
188159
# $2 当前节点路径 (用于标记)
189160
# $3 来源标识
190161
# $4 输出文件
191162
# $5 追加模式 (1=追加,否则覆盖,默认覆盖)
192-
# 返回: 无 (更新 NODE_SCAN_* 计数器)
163+
# 返回: 无
193164
#######################################
194165
scan_nodes_in_dir() {
195166
local dir="$1"
196167
local current_config="$2"
197168
local source="$3"
198169
local output_file="$4"
199170
local append_mode="${5:-0}"
200-
local file tag is_current
201-
202-
# 非追加模式则清空输出文件并重置计数
203-
if [ "$append_mode" != "1" ]; then
204-
: > "$output_file"
205-
reset_node_scan_counters
206-
fi
207171

208-
# 遍历目录下所有 json 节点文件
209-
for file in "$dir"/*.json; do
210-
is_node_config_file "$file" || continue
211-
tag="$(detect_outbound_tag "$file" || true)"
212-
213-
# 无法解析标签的文件计入跳过
214-
if [ -z "$tag" ]; then
215-
NODE_SCAN_SKIPPED_COUNT=$((NODE_SCAN_SKIPPED_COUNT + 1))
216-
continue
217-
fi
218-
219-
# 标记是否为当前使用的节点
220-
is_current=0
221-
[ "$file" = "$current_config" ] && is_current=1
222-
append_node_record "$output_file" "$file" "$tag" "$source" "$is_current"
223-
NODE_SCAN_VALID_COUNT=$((NODE_SCAN_VALID_COUNT + 1))
224-
done
172+
# 非追加模式先清空输出文件
173+
[ "$append_mode" = "1" ] || : > "$output_file"
174+
175+
# 单次 awk 提取各文件首个 tag 并组装记录;无 tag 文件与 _meta.json 自动跳过
176+
awk -v src="$source" -v cur="$current_config" '
177+
# 进入新文件时重置标志并取出文件名 (basename)
178+
FNR == 1 { found = 0; fn = FILENAME; base = fn; sub(/.*\//, "", base) }
179+
180+
# 跳过订阅元数据文件
181+
base == "_meta.json" { nextfile }
182+
183+
# 匹配到首个 "tag": "..." 即提取并输出
184+
!found {
185+
if (match($0, /"tag"[ \t]*:[ \t]*"/)) {
186+
rest = substr($0, RSTART + RLENGTH)
187+
q = index(rest, "\"") # 取到下一个引号为止
188+
tag = (q > 0) ? substr(rest, 1, q - 1) : rest
189+
is_current = (fn == cur) ? 1 : 0
190+
printf "%s\t%s\t%s\t%s\t%s\n", fn, base, tag, src, is_current
191+
found = 1
192+
nextfile
193+
}
194+
}
195+
' "$dir"/*.json 2> /dev/null >> "$output_file"
225196
}
226197

227198
#######################################
@@ -238,9 +209,8 @@ scan_all_nodes() {
238209
local output_file="$3"
239210
local sub_dir source
240211

241-
# 清空输出文件并重置计数
212+
# 清空输出文件
242213
: > "$output_file"
243-
reset_node_scan_counters
244214

245215
# 先扫描默认节点目录
246216
scan_nodes_in_dir "$outbounds_dir/default" "$current_config" "默认节点" "$output_file" 1

0 commit comments

Comments
 (0)