多shell脚本嵌套调用的环境 向外访问网络时暂停 使用者进行替代操作
前言
上一篇我们将 向外访问网络时暂停 使用者进行替代操作 的方案应用在了 安装233boy 脚本上面进一步的, 能不能继续拓展应用范围, 用在, 比如, 我自己的 极简一键脚本中?
bash <(curl -L https://github.com/crazypeace/xray-vless-reality/raw/main/install.sh)
试试
发现有问题.
我的脚本调用了xray官方安装脚本, 在这个嵌套调用的场景下, 被嵌套调用的脚本里的网络访问就没有被抓到.
去问了好多个GPT, 回答了一堆什么线程啊, 进程啊, 环境啊, 继承啊, ...
给了我几个解决方案, 试了一下也是不行. 说明回答的那些理论就是狗屁.
改进
那就来个根本的方案, 在系统PATH中安插假的 curl 和 wget.
我们上个方案里的 curl, wget, __fake_net_common 函数, 都变成可执行文件, 放到 PATH里去. 逻辑都是现成的, 不用大改.
最终我们得到这样的 4 个脚本
fake-curl-wget-v2.sh
#!/usr/bin/env bash# ==========================================# 拦截 curl 和 wget 调用,用于调试/离线测试# ==========================================# 在PATH中设置假命令 curl wgetmkdir -p /tmp/fakebinif [[ ":$PATH:" != *:/tmp/fakebin:* ]]; thenexport PATH="/tmp/fakebin:$PATH"fi# 清理调用记数文件rm /tmp/fakebin/*# 放入假命令文件cp __fake_net_common.sh /tmp/fakebin/fake_net_commonchmod +x $_cp __fake_curl.sh /tmp/fakebin/curlchmod +x $_cp __fake_wget.sh /tmp/fakebin/wgetchmod +x $_# ------------------------------------------# 提示加载成功# ------------------------------------------echo "[INFO] 所有 curl / wget 调用将被拦截"
__fake_net_common.sh
#!/usr/bin/env bash# 调用计数文件(全局共享)COUNT_FILE="/tmp/fakebin/fake_curl_wget_count.tmp"# 如果文件不存在, 初始化为0if [[ ! -f "$COUNT_FILE" ]]; thenecho "0" > "$COUNT_FILE"fi# 锁文件LOCK_FILE="${COUNT_FILE}.lock"# 使用文件锁保护整个执行过程{flock 200 || {echo "[ERROR] 无法获取锁,超时" >&2return 1}cmd="$1"; shiftfake_net_call_count=$(cat "$COUNT_FILE")fake_net_call_count=$((fake_net_call_count + 1))echo "$fake_net_call_count" > "$COUNT_FILE"echo "[DEBUG] curl/wget call # $fake_net_call_count" >&2echo "[DEBUG] Current directory: $(pwd)" >&2printf '[DEBUG] Command: %s ' "$cmd" >&2printf '%q ' "$@" >&2printf '\n' >&2# 是否找到预设命令has_preset=0# 根据调用序号执行预设命令case "$fake_net_call_count" in# 1)# # 示例:第1次调用的预设命令# # echo "preset response for call 1"# has_preset=1# ;;*)# 未设置预设命令echo "[DEBUG] 未设置预设命令" >&2has_preset=0;;esacecho >&2# 如果没有预设命令,进入交互模式if [[ "$has_preset" -eq 0 ]]; thenecho "[WARN] 序号 $fake_net_call_count 未设置预设命令" >&2echo "" >&2echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" >&2echo "请根据 curl/wget的原始命令及参数 进行操作:" >&2echo " - 如需保存文件:请手动上传文件到目标位置,然后输入空行继续" >&2echo ' - 如需输出到stdout:请输入替代命令(如: echo "something" 或 cat /path/file)' >&2echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" >&2echo "[INPUT] 请输入替代命令(或按回车表示文件已上传): " >&2# 读取用户输入read -r user_input </dev/tty# 用户输入空行,表示文件已手动上传# 什么都不用做# 用户输入非空行, 则视为替代命令,执行它if [[ -n "$user_input" ]]; then# 临时移除fake路径,使用真实的curl/wgetexport PATH=$(echo "$PATH" | sed 's|^\(/tmp/fakebin:\)\+||')eval "$user_input"echo >&2# 恢复PATH 加入fake路径export PATH="/tmp/fakebin:$PATH"fifi} 200>"$LOCK_FILE"# 永远返回成功exit 0
__fake_curl.sh
fake_net_common curl "$@"
__fake_wget.sh
fake_net_common wget "$@"
我们把它们4个都上传到VPS上, 再试试.

评论
发表评论