#env-var #applications #executable #shim #environment #target #symlink

app envshim

为使用用户定义的环境变量加载可执行文件的符号链接shim

2 个不稳定版本

0.2.0 2023年10月11日
0.1.0 2023年8月31日

#270 in 配置

GPL-3.0-or-later

22KB
163

EnvShim

EnvShim是一个符号链接shim,用于使用用户定义的环境变量加载可执行文件。下一节将详细介绍这意味着什么。

状态:此项目处于活动状态,并计划发布1.0版本。它目前具有我个人期望的所有功能,并且处于beta质量。然而,它将保持0.x版本一段时间,以识别任何错误或基本需要的功能。不会添加太多功能,因为这可能会减慢程序并延迟最终应用程序的加载。

EnvShim详细介绍

问题:在GNU/Linux桌面上,存在许多定义环境变量的不兼容方式。简单的搜索表明有/etc/profile.d/.bashrc~/.profile~/.xprofile~/.config/environment.d/envvars.conf/etc/environment以及许多其他位置。没有可靠的方法在同一个地方定义所有变量并让所有应用程序都能获取它们。桌面管理器(如SDDM和GDM)处理这些变量的方式也令人惊讶。一些桌面环境(如Gnome和KDE)强制执行定义用户环境变量的标准方式。然而,在窗口管理器(如sway或awesome)中仍然存在问题。

解决方案:EnvShim旨在为用户提供在单个真实来源(~/.config/envshim/script文件)中定义变量的方式,并确保所需的应用程序能够获取这些变量。

EnvShim解决此问题的方法是通过作为目标应用程序的加载shim来操作。为此,将具有与目标应用程序相同名称的envshim可执行文件的符号链接放置在具有比实际目标应用程序在$PATH变量中更高优先级的目录中。以下是一个使用sway可执行文件的示例

_# printenv PATH
/usr/local/sbin:/usr/local/bin:/usr/bin

_# which sway
/usr/bin/sway

_# which envshim
/usr/local/bin/envshim

_# ln -sr /usr/local/bin/envshim /usr/local/bin/sway

_# rehash

_# which sway
/usr/local/bin/sway

在上面的情况下,/usr/local/bin的优先级高于/usr/bin。因此,当我们尝试执行sway时,将通过/usr/local/bin中的符号链接调用envshim,而不是调用/usr/bin/sway。然后EnvShim负责初始化变量,然后调用目标(/usr/bin/sway)。

用户设置: 使其正常工作的第二个要求是声明变量的文件。这必须由用户在主目录下创建,位于 $XDG_CONFIG_HOME/envshim/script。如果 $XDG_CONFIG_HOME 未定义,则假定默认位置 - ~/.config/envshim/script

script 文件是为用户的所选 shell(如 shbash)编写的 shell 脚本。在加载 shim 的时候,envshim 作为子进程调用该 shell,并将脚本的內容传递给它。然后,Envshim 读取脚本的执行结果,并使用它来定义目标应用程序的环境。之后,Envshim 使用 exec 命令进入目标应用程序,用目标应用程序替换自身在进程中的位置。

构建

克隆此存储库并进入它。然后执行正常的 cargo 命令来构建它。之后,将可执行文件复制到所需位置。

git clone https://git.sr.ht/~gokuldas/envshim
cd envshim
cargo build --release
sudo cp target/release/envshim /usr/local/bin

配置

配置过程有两个步骤

1. 脚本文件: 用户必须在 $XDG_CONFIG_HOME/envshim/script 创建脚本文件。它不需要可执行权限。第一行是一个 shebang 行,指示要使用的 shell 并配置为从 stdin 接收输入。以下是一些选项

  • #!/usr/bin/sh -s
  • #!/usr/bin/bash -s
  • #!/usr/bin/zsh -s

将脚本文件填充为以 打印 必要的变量,格式为 VAR=value,每行一个变量。可以使用 echo 来完成此操作,例如。如果希望一次性打印出所有环境变量,可以使用 printenv 命令。只需记住在使用 printenv 之前导出变量。例如

export PATH=$HOME/.local/bin:$PATH

printenv

echo 'ENVSHIM_MARKER=envshim'

此存储库中提供了此文件的示例,位于 assets/script

2. 创建 shims: shims 是具有与目标相同的名称的符号链接,并指向 envshim 可执行文件。这里重要的是要确保 shims 在 $PATH 中位于目标可执行文件之前。例如,如果 PATH=/usr/local/bin:/usr/bin 并且目标应用程序是 /usr/bin/sway,那么 /usr/local/bin/sway 是合理的 shim 选择。要注意的另一件事是这里提到的 PATH 变量是在加载 shim 之前获得的。不要依赖于脚本文件中定义的路径。请参阅 'EnvShim 详细说明' 部分中的示例。

应该选择哪些应用程序进行 shim 加载?以下两条指导原则可以帮助决定。

  1. 任何您希望确保变量正确性的应用程序
  2. 大多数其他应用程序的父进程所在的应用程序

shim 加载会在目标应用程序加载前添加延迟时间,因为必须先运行 shell。第二条指导原则通过减少 shim 加载次数并将结果传递给尽可能多的其他进程来减少此类延迟。以下是一些可能的候选者

  • Shell(如 bash 或 zsh)
  • 窗口管理器(如 sway 或 awesome)

故障排除

Envshim 的设计目的是在任何目标可用的场景下运行目标应用程序。这意味着即使在 shell 或脚本失败或缺失的情况下,目标也将运行。然而,目标收到的环境变量可能不是你期望的。这样的设计是为了避免在出现其他错误时使目标应用程序不可访问。你不希望因为缺少或配置错误的脚本而无法访问 shell 或窗口管理器。

如果你怀疑有这样的安全壳加载,你应该尝试从命令 shell 运行应用程序。如果 EnvShell 遇到任何问题,它会在 stderr 上打印错误消息。

贡献

建议和贡献可以通过以下邮件列表进行。有关如何贡献的详细信息,请参阅我的免费软件索引中的贡献指南项目政策页面。同时,以下额外指南适用:

  1. 在提交之前,使用 rustfmt 格式化代码
    • Markdown 文档的文本宽度为 100
  2. 补丁必须签署(使用以下命令:git commit -s
  3. 使用以下配置设置克隆的本地存储库
git config format.to "~gokuldas/[email protected]"
git config format.subjectPrefix "PATCH EnvShim"
git config format.coverLetter auto
git config format.useAutoBase true
git config format.signOff true

许可证

envshim:将符号链接壳链接到加载具有用户定义环境变量的可执行文件
版权(C)2023 Gokul Das B
SPDX-License-Identifier: GPL-3.0-or-later

本程序是免费软件:您可以重新分发它并/或修改它,具体条款请参阅由自由软件基金会发布的 GNU 通用公共许可证,许可证版本为 3 或(根据您的选择)任何更高版本。

本程序按希望将是有用的,但没有任何保证;甚至没有关于其商业性或针对特定目的的适用性的暗示性保证。有关详细信息,请参阅 GNU 通用公共许可证。

您应已收到本程序的 GNU 通用公共许可证副本。如果没有,请参阅https://www.gnu.org/licenses/

依赖关系

~4–13MB
~167K SLoC