我正在做一个项目,我在 WSL 和bashrc
方面遇到了问题。为了详细说明一点,我有keychain
,我想在每次使用 WSL 命令时运行一个keychain
命令。
所以我在我的~./bashrc
中添加了该命令.
如果我从我的 Windows 终端使用wsl bash -ic "command"
,我在~/.bashrc
中的命令运行。
我现在的问题是,我有另一个程序在没有bash -ic
参数的情况下运行 WSL,我无法更改它。
您知道如何解决此问题或找到解决方法吗?
基本上,我希望每次从Windows终端使用WSL时,它都会首先运行keychain
命令。
例如,假设我想运行wsl git push
. 我希望我的keychain
命令在git push
运行之前执行。
好吧,我已经断断续续地研究了几天,看看我是否可以想出更好的解决方案。 我想不出什么都是最佳的,但我想我最终非常接近。
要重述/构建问题:
-
你需要一个 WSL 发行版来运行某个交互式命令 (
keychain
),该命令将其环境变量加载到用户的 WSL/Bash 会话中。 这需要将密钥加载到ssh-agent
中,以便 IntelliJ 中的wsl git
命令将与您的插件一起使用。 -
如果需要,
keychain
会要求输入密码以加载密钥。 -
keychain
将以可以评估/获取的格式输出ssh-agent
所需的环境变量,并将其反馈到 Bash 会话中。(旁注:我很幸运,我已经使用
keychain
几十年了,所以我对它的流程相当了解)。 -
当使用
wsl git ...
运行时,WSL 将 shell (Bash) 作为非交互式、非登录 shell 启动,因此不处理~/.bashrc
。 因此,即使密钥之前已加载到ssh-agent
(通过keychain
),Bash 会话也没有正确的SSH_AUTH_SOCK
和SSH_AGENT_PID
。
因此,插件中的git
命令可能会对用户失败,因为它们需要基于密钥的身份验证。
我认为以上至少抓住了您要解决的问题的精神。
不幸的是,据我所知,除了修改 WSL 命令行的内容之外,没有一种方法可以强制 Bash 加载其启动文件,因为它是非交互式、非登录 shell。
建议的解决方法 -$WSLENV
链加载 IntelliJ
我相信,这"非常接近"最佳状态。 用户需要通过WSL 启动 IntelliJ,并使用$WSLENV
功能传递正确的环境变量。 这可以以交互方式或通过~/.bashrc
完成。
将以下内容添加到~/.bashrc
:
eval $(keychain --eval ~/.ssh/<keyfile>)
export WSLENV=$WSLENV:SSH_AGENT_PID:SSH_AUTH_SOCK
完成此操作后,您应该能够运行:
wsl -e bash -lic /path/to/intellij.exe
它将询问密钥密码并(像往常一样)将SSH_AGENT_PID
/SSH_AUTH_SOCK
环境变量添加到 shell 会话中。它还会将这些变量名称添加到$WSLENV,以便将它们传递给从 WSL 内部启动的任何Windows进程。
当 IntelliJ Windows 可执行文件以这种方式启动时,这三个变量也将在其环境中可用:
WSLENV
SSH_AGENT_PID
SSH_AUTH_SOCK
当IntelliJ然后运行wsl git ...
时,这三个变量也将传递回WSL,以便git
能够从ssh-agent
访问密钥。
虽然我没有IntelliJ,但我已经成功地测试了它:
wsl -e bash -lic pwsh.exe # or powershell.exe
然后,从PowerShell:
> $env:WSLENV
WT_SESSION::WT_PROFILE_ID:SSH_AGENT_PID:SSH_AUTH_SOCK
> $env:SSH_AGENT_PID
45
> $env:SSH_AUTH_SOCK
/tmp/ssh-XXXXXXTWbsTa/agent.44
> cd some-dir
> wsl git clone "git@github.com:NotTheDr01ds/<private_repo>"
它按预期工作。
其他选项
如果您的用户正在使用(或愿意使用)Bash以外的一些shell,这实际上会更容易一些:
Fish shell 启动文件甚至来源于非登录、非交互式 shell,此外它还支持"通用变量",允许
SSH_A*
变量自动提供给所有正在运行(和将来)的 Fish 实例。Zsh 有一个启动文件(
~/.zshenv
),它来源于非登录、非交互式 shell。 它比 Fish 复杂一点,但它是可行的。
实际上,在我发现$WSLENV
是一个可行的解决方案(不需要更改外壳)之前,我实际上将这些作为建议的解决方案开始。 但是,如果您想查看我关于如何在 Zsh 或 Fish 中执行此操作的文章,请查看此答案的编辑历史记录。
在 Windows 11 上,您可以在 wsl 启动时运行脚本,创建或编辑(作为 sudo)/etc/wsl.conf
,内容如下:
[boot]
command="command to run"
在此处添加所需的命令。