无法从 WSL bash 中的批处理文件运行 Homebrew 应用程序(找不到命令)

Posted

技术标签:

【中文标题】无法从 WSL bash 中的批处理文件运行 Homebrew 应用程序(找不到命令)【英文标题】:Can't run a Homebrew app from batch file in WSL bash (command not found) 【发布时间】:2021-04-05 19:25:50 【问题描述】:

我有一个 bash 脚本,其中包含以下命令,包括将文件传递给 eyeD3,我使用 Homebrew 安装它:

#!/usr/bin/env bash
cd /mnt/c/Users/charl/Downloads;
eyeD3 test.mp3;

当我从 Ubuntu bash 提示符在 Windows 子系统 Linux (WSL) 中运行它时,我得到了正确的结果:

thompcha@WINDOWS-79UTJUF:/mnt/c/Users/charl/Documents/Scripts$ ./eyed3.sh
/mnt/c/Users/charl/Downloads/test.mp3                                                     [ 7.15 MB ]
-----------------------------------------------------------------------------------------------------
Time: 04:26     MPEG1, Layer III        [ 224 kb/s @ 44100 Hz - Stereo ]
-----------------------------------------------------------------------------------------------------
ID3 v2.4:
title: Example Song
artist: Example Artist
album: Example Album
track: 1
-----------------------------------------------------------------------------------------------------

但是,如果我从这样的批处理文件中运行 bash 脚本,

@ECHO OFF
bash.exe -c ./eyed3.sh
PAUSE

eyeD3 命令无法运行:

./eyed3.sh: line 3: eyeD3: command not found
Press any key to continue . . .

ls 这样的默认系统命令可以通过批处理文件调用的shell 脚本以这种方式运行,但eyeD3 不能。我猜脚本以这种方式运行时无法“看到”环境 $PATH,但我不确定该怎么做。

我在 cmd.exe 属性中未选中“使用旧版控制台”。

如何在批处理文件的 shell 脚本中运行自制命令?

【问题讨论】:

在 shell 脚本中引用带有完整限定文件名的可执行文件 eyeD3 会发生什么,即在 Windows Subsystem for Linux 环境中使用完整路径? Re:Mofi 的评论——例如,在 shell(你知道它可以工作的地方)中,执行 which eyed3,然后在 shell 脚本中硬编码完全限定的路径。 @NotTheDr01ds 这个命令产生了/home/linuxbrew/.linuxbrew/bin/eyeD3,它很有魅力!运行不包含路径的命令时,有没有办法让它包含此路径? 【参考方案1】:

简答 - 几个选项:

选项 1:将其更改为 bash.exe -l -c ./eyed3.sh。我很确定这会奏效(请参阅下文了解“为什么”)。 选项 2:根据 cmets,在其工作的终端中使用 which eyeD3 标识 eyeD3 可执行文件的位置,然后在 shell 脚本中硬编码完全限定的路径。 选项 3:在 .bashrc 而不是 .profile(Homebrew 设置的位置)中设置 Homebrew 路径。

/aside:哇,我用 eyeD3 已经 15 年多了。令人惊讶的是,它还在附近并在踢!

发生了什么

我不运行 Homebrew,但查看它的 install script(最后 10 行左右)证实了我的预感,它在安装过程中将其路径添加到您的 .profile(或其他适用的启动脚本)。

.profile(或.bash_profile 或...)仅用于登录shell(通常是生成其他非登录shell 的“***”shell)。这是登录时应该只做“一次”的事情的地方,而不是在每个 shell 实例中。这里设置PATH是因为导出到子shell,所以不需要每次都设置。

所以当你运行bash.exe -c ./eyeD3.sh 时,它实际上是一个非登录shell,它会跳过登录启动脚本,从而跳过Homebrew 添加的修改PATH 的代码。使用 -l 参数运行 bash 将导致它作为登录 shell 运行,从而获取 Homebrew 代码并修改该 shell 的 PATH。

如果您有兴趣,请参阅this answer 了解有关不同类型启动脚本的更多详细信息。

【讨论】:

以上是关于无法从 WSL bash 中的批处理文件运行 Homebrew 应用程序(找不到命令)的主要内容,如果未能解决你的问题,请参考以下文章

从 WSL 运行某些东西的 Windows bash 脚本

Bash On Windows(WSL)无法运行32Bit程序,报错cannot execute binary file: Exec format error解决办法

当 Docker 桌面在 WSL2 中运行时,bash 中的长工作目录

我可以将退出代码 %errorlevel% 从 WSL Bash 返回到 Powershell 或命令提示符吗?

将 WSL(Windows 上的 Bash)根文件系统移动到另一个硬盘驱动器?

wsl2从bash终端调用浏览器打开localhost