用 Shell 包装函数,让单个命令拥有专属配置

背景

访问 GitHub 的网络连接时通时断,GitHub CLI(gh)经常超时。git 可以按域名设置代理(http.<url>.proxy,只对 github.com 生效),gh 却只认 HTTPS_PROXY 环境变量。而 export HTTPS_PROXY 是全局的:shell 里所有命令的请求都会经过这个代理,包括公司内网仓库、gitee 等在内,代理服务不可用时这些命令全部失败。

需求是:只有 gh 经过代理,其余命令不受影响。

一行解法

bash 复制代码
gh() { HTTPS_PROXY=http://127.0.0.1:7890 HTTP_PROXY=http://127.0.0.1:7890 command gh "$@"; }

拆开看四个部分:

片段 作用
gh() { ...; } 定义与命令同名的包装函数:敲 gh 时优先命中函数,而不是去 PATH 找原始程序
VAR=值 写在命令前 单命令环境变量:只对紧跟的这条命令的进程生效。不是 export,不留在 Shell 里,也不传递给其他命令
command gh 内置关键字,绕过函数直接调用原始程序,避免函数调用自己造成无限递归
"$@" 原样透传所有参数,每个参数独立引号包裹

验证方法:先 export HTTPS_PROXY=http://127.0.0.1:9(一个故意写错的地址)再调用 gh,依然能成功,说明函数内部的赋值覆盖了外部变量;调用后执行 env | grep -i proxy,没有输出,说明变量没有泄漏到 Shell 环境。

覆盖两个世界

bash 读取配置的规则按启动模式分成两条互不相通的通道:

  • 交互 shell(手动打开的终端):读取 ~/.bashrc,不读 BASH_ENV
  • 非交互 shell(脚本、AI 编程会话中执行的命令):只读 BASH_ENV 指向的文件,不读 ~/.bashrc

完整的做法是一处定义、两处引用:

bash 复制代码
# ~/.bash_env.sh ------ 函数唯一定义处,保持极简
export PATH="/c/Program Files/GitHub CLI:$PATH"
gh() { HTTPS_PROXY=http://127.0.0.1:7890 HTTP_PROXY=http://127.0.0.1:7890 command gh "$@"; }
bash 复制代码
# 设置用户环境变量,全机所有非交互 bash 启动时自动加载上面的文件
setx BASH_ENV "C:/Users/you/.bash_env.sh"

# 在 ~/.bashrc 末尾引用同一个文件,交互 shell 由此获得同一个函数,保持单一来源
echo '. ~/.bash_env.sh' >> ~/.bashrc

git 原有的按域名代理配置不受影响,gh 与 git 各自使用各自的规则。

其他适用场景

凡是"只想让某个命令带上特殊环境变量"的场景,都可以用同样的写法:

bash 复制代码
mvn() { JAVA_HOME=/path/to/jdk8 command mvn "$@"; }              # 老项目固定 JDK8
node() { NODE_OPTIONS=--enable-source-maps command node "$@"; }  # 单命令开启 source maps
docker() { DOCKER_HOST=ssh://dev-box command docker "$@"; }      # 指定远程 docker

不再需要时删掉函数即可,没有残留。

两点注意

  1. 函数体内只用"单命令环境变量"写法,不要写 export,否则作用域会从单个进程扩大到整个 Shell;
  2. BASH_ENV 指向的文件会在全机每个非交互脚本执行前被加载,内容应保持极简,不要放入 sdkman 初始化这类较重的逻辑。

小结

包装函数加单命令环境变量,可以把一份配置的作用域限定到单个命令的进程:需要它的命令拿到它,其他命令不受影响。


(END)

相关推荐
高调的涵涵12 小时前
删了1.2GB,.git仍是1.2GB
git
程序员沉梦听雨13 小时前
【Git】git-submodule子模块管理
git
全栈陈序员1 天前
Git】从入门到精通(八)—— git log:查看提交历史
大数据·git·elasticsearch
7177772 天前
Git自建用什么工具比较好:Gitea、Forgejo、GitLab CE与Gitee的选型对比
git·gitlab·gitea
lsc_blog2 天前
年底还在招的岗位,先确认缺口和到岗要求
git·缓存·ci/cd·职场和发展·github
全栈陈序员3 天前
【Git】从入门到精通(十一)—— git reset 三种模式详解
git·elasticsearch
全栈陈序员3 天前
【Git】从入门到精通(十)—— 撤销与恢复:git checkout与git restore
运维·网络·数据库·git
全栈陈序员3 天前
【Git】从入门到精通(五)—— git add:将文件加入暂存区
大数据·git·elasticsearch
全栈陈序员3 天前
【Git】从入门到精通(七)—— git status:查看仓库状态
大数据·git·elasticsearch
莫晓燚3 天前
Ansible 13 个常用模块---企业实战
git·github