在 ConEmu 启动任务中使用 WSL 运行 zsh 别名 简答:第 1 步:启动 wsl.exe,运行别名,并防止会话退出在 ConEmu 启动时运行命令替代方案:修改现有的 zsh 以运行基于环境变量的别名

问题描述

我当前的 WSL2 + ConEmu + bash/zsh 设置按预期工作。

我在 .zshrc 中设置了一些别名:

//.zshrc
alias mycommand1="[does some stuff]"
alias mycommand2="[does other stuff]"

我想要实现的是有一个 ConEmu 启动任务,它会在两个单独的选项卡中运行 mycommand1mycommand2,然后让这些选项卡保持打开状态。 >

这需要ConEmu加载WSL+bash+zsh,然后运行命令。

根据 the docs,我的认任务当前运行原生 wsl.exe:

// {Bash::bash} Task commands
%windir%\system32\wsl.exe -cur_console:pm:/mnt --distribution Ubuntu-20.04

而且,在仔细阅读所有文档123)并花费大量时间摆弄参数之后,我只能产生以下尝试:

%windir%\system32\wsl.exe --distribution Ubuntu-20.04 -new_console:pm:/mnt -- ls
// logs my Windows User directory and prompts "Press Enter or Esc to exit..."
%windir%\system32\wsl.exe --distribution Ubuntu-20.04 -new_console:pm:/mnt -- mycommand1
// logs "zsh:1: command not found: mycommand1" and prompts "Press Enter or Esc to exit..."

我希望得到一些建议:

  • 如何从 wsl.exe 传递将在 Ubuntu 上下文中运行的命令,以及我的所有 bash/zsh 配置?
  • 如何从 ConEmu Task 执行此操作,确保在运行命令后选项卡在常规 zsh shell 提示下保持打开状态?
  • 还有什么我需要知道才能解决我的问题吗?

解决方法

简答:

  • 使用新的 .zshrc 创建一个新的启动目录,该目录 (a) 提供现有配置文件,以及 (b) 根据启动 shell 之前设置的环境变量运行别名。
  • 通过设置 ZDOTDIRRUN_ALIASexec 来启动每个 shell(选项卡)
  • 通过 zsh -li 命令运行这些
  • 设置 ConEmu 启动文件以运行适当的命令

第 1 步:启动 wsl.exe,运行别名,并防止会话退出

假设:我将假设您确实希望这些成为别名。如果您想运行其他任意脚本/命令,您仍然可以这样做,但需要对说明稍作更改。我在下面总结了所需的更改。

您可以使用多种技术来保持 shell 运行,但建议的 in this question 要求您:

  • 创建一个嵌套的 shell,这并不理想。
  • 或者 modify 您现有的 zsh 以“特殊情况”使用您的命令启动。这是一个巧妙的技巧,但我不喜欢更改可以避免的默认启动文件。也就是说,这要容易得多。如果你想走这条路,我会在这个答案的底部添加一些关于如何去做的信息。

但是 ~/.zshrc 解决方案让我思考。如果您想在启动时运行任意命令,同时保持 shell 运行,答案 ~/.zshrc。 您只需要有一个 不同的 .zshrc 用于“特殊情况”。

.zshrcbash 选项来选择在启动时运行的文件,但 --rcfile 等价物有点棘手,因为它涉及设置 zsh 并更改$ZDOTDIR 从中读取其启动的位置(来自 this answer)。

首先,让我们为您的“运行别名”配置创建一个配置目录:

zsh

当然,或者你想要的任何地方。然后,在该目录中,创建以下内容:

mkdir -p ~/.local/share/zsh/startup/run_alias/`

~/.local/share/zsh/startup/run_alias/.zshrc

还有if [ -f $HOME/.zshrc ]; then . $HOME/.zshrc fi if [ -v RUN_ALIAS ] && alias | grep -q "^$RUN_ALIAS="; then eval "$RUN_ALIAS" fi unset RUN_ALIAS unset ZDOTDIR

~/.local/share/zsh/startup/run_alias/.zprofile

当然,如果您始终知道您的 if [ -f $HOME/.zprofile ]; then . $HOME/.zprofile fi $HOME/.zsh 存在,则条件是可选的。但最好还是安全一点。

重复 .zprofile

如果不明显,这将:

  • 调用您现有的 mycommand2 来定义别名(以及您启动中的任何其他内容)
  • 检查以确保 $HOME/.zshrc 的内容确实是别名(一些增加的安全性)
  • 调用 $RUN_ALIAS 变量中定义的别名
  • 取消设置 RUN_ALIAS 变量(清理)
  • 取消设置特殊的 RUN_ALIAS,以便将来的子 shell 调用将使用 ZDOTDIR 中的文件。
  • 让新的 $HOME 也有原始来源

您现在可以通过调用子shell来测试:

.zprofile

当然,这会留下一个额外的子shell 运行(ZDOTDIR=~/.local/share/zsh/startup/run_alias RUN_ALIAS=mycommand1 zsh -li 是 2)。因此,请改用 $SHLVL

exec

$SHLVL 现在是 1,你的命令/别名应该已经在当前(也是唯一的)shell 中执行了,并且它仍在运行。

为了让它在 WSL 中运行,我们确实需要启动一个“外壳”(被 ZDOTDIR=~/.local/share/zsh/startup/run_alias RUN_ALIAS=mycommand1 exec zsh -li 正确的 exec 替换)。为此,我倾向于使用 zsh,如下所示:

sh

旁注:我的 wsl ~ --distribution Ubuntu-20.04 --exec sh -c "ZDOTDIR=`$HOME/.local/share/zsh/startup/run_alias RUN_ALIAS=mycommand1 exec zsh -li" # PowerShell quoted wsl ~ --distribution Ubuntu-20.04 --exec sh -c "ZDOTDIR=$HOME/.local/share/zsh/startup/run_alias RUN_ALIAS=mycommand1 exec zsh -li" # CMD (and ConEmu) quoted 的 Windows 终端配置文件实际上看起来与此非常相似。我对它们进行了一些简化,但在启动我的 shell (wsl) 和 fish 之前,我仍然设置了一个环境变量(我想要的标签标题)。

旁注 #2:我最初的回答使用了两个单独的 tmux 和相应的目录。如果您想执行不同的命令(而不是别名),这仍然很有用。在这种情况下,创建其他目录,并通过更改 ZDOTDIR 来指向它们。只需将您的命令放在相应目录中修改后的 ZDOTDIR 中即可。

在 ConEmu 启动时运行命令

容易的部分。在任何地方(和任何名称)创建一个 .zshrc,真的:

conemu_start.txt

在 ComEmu 中,将 Settings -> Startup -> Tasks file 设置为该文件。

应该可以。启动 ConEmu 现在应该打开两个带有 >%windir%\system32\wsl.exe -cur_console:t:"MyCommand1" -cur_console:pm:/mnt ~ --distribution Ubuntu-20.04 --exec sh -c "ZDOTDIR=$HOME/.local/share/zsh/startup/run_alias RUN_ALIAS=mycommand1 exec zsh -li" >%windir%\system32\wsl.exe -cur_console:t:"MyCommand2" -cur_console:pm:/mnt ~ --distribution Ubuntu-20.04 --exec sh -c "ZDOTDIR=$HOME/.local/share/zsh/startup/run_alias RUN_ALIAS=mycommand2 exec zsh -li" 的选项卡,每个别名/命令一个。

替代方案:修改现有的 zsh 以运行基于环境变量的别名

将以下内容添加到 .zshrc 的底部:

~/.zshrc

测试:

if [ -v RUN_ALIAS ] && alias | grep -q "^$RUN_ALIAS="; then
  eval "$RUN_ALIAS"
fi

然后将 RUN_ALIAS=mycommand1 exec zsh -li 更改为:

conemu_start.txt
,

将其添加为第二个答案,以防它对您有用(而且很可能)。

我的(很长)其他答案假定您需要别名在继续运行的同一个子shell 实例中运行。如果您对运行别名没问题,然后exec使用 shell,那么这个答案将简单得多

只需创建一个 conemu_start.txt(或任何您想将其命名的名称,无论您想将其放置在何处),使用以下内容:

>%windir%\system32\wsl.exe -cur_console:t:"MyCommand1" -cur_console:pm:/mnt ~ --distribution Ubuntu-20.04 --exec zsh -li -c "mycommand1; zsh -li"
>%windir%\system32\wsl.exe -cur_console:t:"MyCommand2" -cur_console:pm:/mnt ~ --distribution Ubuntu-20.04 --exec zsh -li -c "mycommand2; zsh -li"

与其他答案一样,在 ComEmu 中,将 Settings -> Startup -> Tasks file 设置为此文件。

就是这样。 -li 将导致 shell login(处理 .zprofile)和 interactive(处理 .zshrc)。这样,别名会被定义、执行,然后运行另一个子 shell 以保持 ConEmu 选项卡打开。