感谢周年更新,我现在在 Windows 10 上的 Ubuntu 上有了 BASH。以前,我使用 Cygwin,并在 Cygwin 中设置了 Maven(并使其完全正常工作),这主要包括安装 Maven,然后修改我的PATH
环境变量(在~/.bashrc
)
好吧,我正在尝试使用 BUW 做同样的事情,但据我所知,变量PATH
被忽略了(将 Maven bin 目录添加到PATH
,然后执行which mvn
返回空白)。我是不是错过了什么技巧,还是我必须在 BUW 中以不同的方式设置PATH
?
编辑:
让我具体说一下。我需要在“???”步骤中做什么才能将 pathTestScript.sh 放到路径上?
mkdir -p ~/pathTest
touch ~/pathTest/pathTestScript.sh
echo '#!/bin/sh' >> ~/pathTest/pathTestScript.sh
echo 'echo "it works!"' >> ~/pathTest/pathTestScript.sh
bash ~/pathTest/pathTestScript.sh
# Should output 'it works!'
# ?????????
pathTestScript.sh
# Should output it works!'
编辑2:
我想非常清楚我的实际最终目标。我在系统的常用位置安装了 JDK 和 Apache Maven。这两个软件在 Cygwin 中运行良好。现在 BUW 已经发布,我想在那里使用它们,但我不知道如何为它们设置环境,因为我对 PATH 所做的任何更改似乎都没有任何效果。
编辑3:
好吧,现在我担心自己是在徒劳无功。如果我这样做echo $PATH
,我会/mnt/c/Program\ Files/apache-maven-3.3.9/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
这就是我所期望的。这就是我放入~/.bashrc
文件中的内容……然后我这样做ls /mnt/c/Program\ Files/apache-maven-3.3.9/bin
,得到了
m2.conf mvn mvn.cmd mvnDebug mvnDebug.cmd mvnyjp
但是当我这样做时which mvn
,我得到的是空白,如果我调用mvn
,我被重定向到使用apt-get
来安装它。
所以问题不在于 PATH 没有更新……它只是被忽略了。有没有办法让它注意 PATH?如果没有,这是一个相当弱的 Linux 版本(在我看来)
编辑4:
这个问题已经提过几次了,是的,我草草写的例子忘记将文件标记为可执行文件。在我的实际场景中(使用 Maven),这些文件都是可执行的:
cd /mnt/c/Program\ Files/apache-maven-3.3.9/bin && ls -alt
total 36
dr-xr-xr-x 2 root root 0 Apr 19 11:56 ..
-r-xr-xr-x 1 root root 1843 Apr 19 11:56 mvnyjp
dr-xr-xr-x 2 root root 0 Apr 19 11:56 .
-r-xr-xr-x 1 root root 1815 Apr 19 11:56 mvnDebug
-r-xr-xr-x 1 root root 7383 Apr 19 11:56 mvn
-r-xr-xr-x 1 root root 1513 Apr 19 11:56 mvnDebug.cmd
-r-xr-xr-x 1 root root 6067 Apr 19 11:56 mvn.cmd
-r-xr-xr-x 1 root root 230 Apr 19 11:56 m2.conf
答案1
更新摘要
所讨论的可执行文件不是 Linux 本机格式 (ELF),它们是为 Windows 编译的。在路径扩展期间,bash 会检查二进制文件的魔数,如果它与 ELF 不匹配,则不会通过路径扩展来公开它。但是,Windows 版 bash 确实包含从 bash 环境启动本机 Windows 应用程序的功能,这就是为什么直接执行(无需路径扩展和随后的二进制检查)可以正常工作的原因。
解决方案要么是基于别名的 .bashrc 添加(或任何数量的替代方法来模拟路径扩展从而绕过 bash 文件评估),要么安装 linux 版本。
原始答案
文件权限
这可能是跨文件系统权限问题。如果您cd /mnt/c/Program\ Files/apache-maven-3.3.9/bin
尝试像这样运行 mvn,./mvn
会发生什么?
ls -alt
该目录中的输出是什么?
如果文件未正确标记为可执行文件,则它不会显示为路径上的“程序”。如果它是二进制文件且不是“linux”格式 (ELF),则它也不会显示为路径可执行文件。
如果直接执行 mvn 不起作用(请发布 ls 结果),请尝试添加执行权限chmod ug+x mvn
安装错误版本
您确定安装了 Linux 原生版本吗?与 cygwin 一起使用的版本几乎肯定无法工作。
您可以
sudo apt-get install elf-binutils
使用 mvn 检查二进制兼容性,然后在文件上使用命令
readelf -a mvn
如果收到诸如“不是 ELF 文件......”之类的错误,那么您就有答案了。
我刚刚注意到您没有在示例中为测试 shell 脚本添加执行权限,这(除非您只是忘记列出步骤)完全解释了那个特定的失败。
概括:
- 确保使用 chmod 将 maven bin 目录中的可执行文件正确设置为可执行文件。将 ls -alt 的输出发布到您的答案中。
- 确保您有一个 Linux 二进制文件 - 使用实用程序 readelf 来验证。
- 再次运行你的 shell 脚本测试,但这次将文件标记为可执行文件。
更新
路径问题只是一个幌子;您只是试图执行与 Windows 环境上的 Linux 不兼容的二进制格式。
从表面上看,这两个环境(cygwin 和 Windows 上的 bash)提供了类似的用户体验,但实现和由此产生的二进制兼容性却有很大不同。
底线 - Cygwin 和 Linux 二进制格式不兼容。您需要安装 Linux 本机版本才能从 Windows 上的 Bash 运行它。您也可以在 Windows 上的 Bash 环境中从源代码编译它;但由于环境的“早期”性质,我担心追逐依赖关系。
两个环境简单描述一下:
Cygwin 实际上是一个转换层,它为非 POSIX 系统上通常不可用的系统调用提供 API,这允许您在 Windows 环境中编译许多在 Linux 上运行的程序。但是它仍然在“Windows”环境中运行 - 该二进制文件现在只能在 Windows 上的 cygwin 环境中运行。此转换层和相关库允许针对 Linux API 编写的源代码在 cygwin 环境中编译并在 Windows 上运行。以这种方式构建的二进制文件不会在 Linux 或 Windows 上本机运行;只能在 cygwin 环境中运行。
canonical 提供的 Windows 上的 bash 环境与 cygwin 有很大不同。它实际上为看起来确实是 Linux 的程序“重新创建”了一个环境 - 即标准库与 POSIX 系统调用一起可用 - 而无需对二进制文件进行任何修改。在许多情况下,针对 ubuntu 构建的二进制文件可以直接复制到 Windows 上的 bash 环境并运行而不会出现任何问题。
要在 Windows 上的 Bash 中被识别为有效可执行文件,它必须是原生 Linux 二进制格式或标有解释程序的脚本文件(对于 Bash 脚本,为 #!/bin/bash)。原生 Linux 二进制文件将针对 Linux 库和系统调用进行构建。Bash 通过检查可执行权限位和检查二进制文件格式是否兼容(“魔术数字”检查)来确认某个文件是否为有效可执行文件。如果该文件是二进制文件且不是 ELF 格式,则不会通过路径扩展将其暴露给 Shell。
为了使这个问题更难澄清,他们增加了从 Windows 上的 Bash 启动本机 Windows 应用程序的部分功能,但显然没有解决 Bash 路径扩展二进制文件格式检查 - 或者他们解决了,但这是一个错误。
第二次编辑:
澄清您的问题:
当您直接启动它(./mvn)时,它会绕过 Bash 评估并直接执行它。Windows 环境中的 bash 足够智能,可以启动 Windows 本机可执行文件,这一定是这样的。我不相信 cygwin 二进制文件可以从 bash 正确启动,但我可能是错的 - 目前文档很少,而且我现在没有可用的测试环境。
提供与“路径”支持等效功能的解决方法:
如果您对 maven 安装完全满意(没有其他兼容性问题,一切都正常),但将其放在路径上很重要,则可以使用一个简单的解决方法来提供等效的功能。
在您的 .bashrc 文件中,添加以下别名:
alias mvn='/mnt/c/Program\ Files/apache-maven-3.3.9/bin/mvn'
对您想要从 Windows 环境上的 Bash 中的任何位置访问的该目录中的任何其他可执行文件重复等效操作。
重新启动 bash 或源文件,然后mvn
就可以从任何目录工作了(基于您所说的直接从 bin 目录 ./mvn 中执行是可行的)。
答案2
尝试
echo 'PATH="~/pathTest/:$PATH"' > ~/.bash_path
(任何你想要的名字)
source ~/.bash_path
echo $PATH
看看是否有什么变化
chmod +x ~/pathTest/pathTestScript.sh
为了直接运行它,您必须为该文件添加执行权限。
pathTestScript.sh
如果有效,只需source ~/.bash_path
在中添加该行即可~/.bashrc
。
您可以通过 来调用吗/mnt/c/Program\ Files/apache-maven-3.3.9/bin/mvn
?
答案3
因为它基于 Ubuntu,所以实际的 PATH 文件是“ /etc/environment
”(不显示文件类型)。
$ nano /etc/environment
是编辑文件最简单的方法。您将看到类似以下内容的内容:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
您可以在最后一个目录之后的最后一个引号之前添加您选择的目录,并使用附加冒号:
来与前一个目录分隔。
最后,您必须运行文件“ /etc/environment
”;这可以通过输入以下内容来完成:
$ . /etc/environment
我运行了这些$ sudo -s
并进行了检查$ env
。我有点相信 env 命令应该显示即时更改,并且在完成所选更改后重新启动应该会将其完成。