如何在网络连接上自动更新系统范围内的 $http_proxy 变量?

如何在网络连接上自动更新系统范围内的 $http_proxy 变量?

有时我需要通过手机进行连接。问题是当我这样做时,它使用随机私有IP作为网络网关。谷歌似乎认为他们拥有你的手机,而不是你,所以我对这种行为没有太多控制权。此外,我在其上运行代理应用程序。我想做的是自动设置它。

我有以下脚本:

#!/usr/bin
router=$(route -n | awk '{print $2}' | grep 192.168)
sed "s/\[PROXY-IP\]/$router/g" ~/pac/wpad.template > ~/pac/wpad.dat
export http_proxy="http://$router:8080"
export https_proxy="https://$router:8080"
export ftp_proxy="http://$router:8080"

但是,当我检查环境变量时,它们尚未设置,但 wpad.dat 已更新。所以我知道脚本运行了。

我了解到 shell 脚本不会访问系统环境变量。只是本地副本。有没有办法在系统范围内设置这些变量?我能找到的唯一建议是每次网络发生变化时都需要重新启动。这将是非常具有破坏性的。基本上将脚本硬编码到 .bashrc 中

我已经研究了源命令,但这似乎只适用于所谓的脚本。这些更改不会向上传播到系统和用户变量。我不知道他们是怎么做到的,因为任何调用脚本的源都会在它自己的环境变量的本地副本上运行。

答案1

更新 WPAD 文件对于 Firefox 等 GUI 浏览器应该可以正常工作(假设它们已配置为使用它)。

lynx像或wget之类的命令行工具curl要困难得多:

  • 他们无法使用 PAC 或 WPAD 文件
  • 您甚至无法更改进程父进程中的环境变量,更不用说全局了。
  • 并且无法告诉 shell 在文件更改时重新获取文件源。

除了那里完成最后一项的方法。bash至少在。您可以使用 PROMPT_COMMAND 变量来指示bash每次显示 shell 提示符时获取脚本。例如:

修改您的脚本,以便将 *_proxy 变量设置输出到文件,例如/var/tmp/proxy-settings.sh.确保该文件是世界可读的,扩展名为chmod a+r.

就像是:

cat <<__EOF__ > /var/tmp/proxy-settings.sh
export http_proxy="http://$router:8080"
export https_proxy="https://$router:8080"
export ftp_proxy="http://$router:8080"
EOF

然后编写一个 shell 脚本来获取该文件(如果该文件已更改),并将其另存为,例如/usr/local/bin/update-proxy-vars.sh.同样,这应该是单词可读的 ( chmod a+r)。它不需要是可执行的,因为它将被获取,而不是被执行:

# each individual shell needs it's own timestamp, because each one will
# read the proxy settings file at different times.
mkdir -p /tmp/.proxy-timestamps

tsfile="/tmp/.proxy-timestamps/time/var/tmp/proxy-settings.sstamp.$$"
if [ -e "$tsfile" ] ; then
  timestamp=$(< "$tsfile")
fi

# get the timestamp of the proxy-settings.sh file
# not all versions of `stat` can do this, and those that do
# have different and incompatible options.  The following works
# for GNU `stat`.
proxy_timestamp=$(stat -c %Y /var/tmp/proxy-settings.sh)

# has the timestamp changed?  if so, source the file.
if [ "$timestamp" != "$proxy_timestamp" ] ; then
  . /var/tmp/proxy-settings.sh
  echo "$proxy_timestamp" > "$tsfile"
fi

最后,设置 PROMPT_COMMAND 以在每次显示提示时获取此脚本。

PROMPT_COMMAND='. /usr/local/bin/update-proxy-vars.sh'

您还应该rm -f /tmp/.proxy-timestamps/timestamp.$$在 ~/.bash_logout 脚本中运行,以便在 bash 退出时进行清理。

在我看来,这是一种丑陋且令人讨厌的黑客行为,而且它会减慢速度bash(一开始就不是速度恶魔),因为它必须在update-proxy-vars.sh每次显示提示时运行。每次运行命令时。或者直接按回车键而不输入任何命令。每次提示时,都必须运行此脚本,读入时间戳文件,运行stat,比较时间戳,如果时间戳已更改,则可能需要获取另一个文件。

/var/tmp/proxy-settings.sh每次只获取源(如果存在),无论它是否已更改,而不用担心时间戳,可能会更快。

只需设置:

PROMPT_COMMAND='[ -e /var/tmp/proxy-settings ] && . /var/tmp/proxy-settings.sh'

但它有效,这是最重要的,对吗?

或者您可以养成记住手动获取文件的习惯,就像/var/tmp/proxy-settings.sh在每个需要它的 shell 中一样。

$PS1您可能可以在其他 shell 中使用该变量(例如ashdashzshksh等)执行相同的操作。但这个使用 PROMPT_COMMAND 的版本已经够丑陋和hacky了。这样做的话PS1会更糟糕。

答案2

您必须对文件进行源调用(文件调用前的点): 。 ./myfile.sh

通常,文件仅获取父环境的副本,并且在关闭环境中子进程的会话机会后会丢失

相关内容