![为什么 Java 代码可以手动运行,但不能通过 Shell 脚本运行?](https://linux22.com/image/1186065/%E4%B8%BA%E4%BB%80%E4%B9%88%20Java%20%E4%BB%A3%E7%A0%81%E5%8F%AF%E4%BB%A5%E6%89%8B%E5%8A%A8%E8%BF%90%E8%A1%8C%EF%BC%8C%E4%BD%86%E4%B8%8D%E8%83%BD%E9%80%9A%E8%BF%87%20Shell%20%E8%84%9A%E6%9C%AC%E8%BF%90%E8%A1%8C%EF%BC%9F.png)
您好,有一个令人沮丧的问题:在我的 Ubuntu 22.04 机器上,我有一些 Java/Maven 代码,我可以从命令行手动运行:
me@UbuntuV2:~/home/me/path/to/Java/Code$
me@UbuntuV2:~/home/me/path/to/Java/Code$ mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------< MyCode.java >--------------------
...code runs fine...
这很好,但我需要从 shell 脚本运行相同的代码:
#!/bin/bash
echo "Running the script!"
cd /home/me/path/to/Java/Code
mvn test
echo "Script finished."
奇怪的是,脚本可以启动Java代码,但是脚本运行代码却抛出了异常:
me@UbuntuV2:~/home/me$
me@UbuntuV2:~/home/me$ ./runScript.sh
Running the script!
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------< MyCode.java >--------------------
2022-03-02 12:29:44,899 main ERROR Unable to access file:/home/me/path/to/Java/Code/src/test/resources/log4j2.xml java.io.FileNotFoundException: /home/me/path/to/Java/Code/src/test/resources/log4j2.xml (No such file or directory)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
at java.base/java.io.FileInputStream.(FileInputStream.java:157)
...etc...
这太奇怪了,对吧?当通过 shell 脚本运行时,Java 代码突然无法访问“log4j2.xml”文件。(“没有这样的文件或目录”)但该文件就在那里,当我手动运行代码时,代码可以毫无问题地打开它。
那么,当我手动运行代码时会有什么不同?我绞尽脑汁想出可能有什么不同。我做了以下所有事情:
- 已验证用户是否
me
从 bash shell 手动运行代码,就像脚本一样。 - 以用户身份运行脚本
me
,该用户与可以手动运行代码的用户相同 - 通过在脚本中
me
添加命令来检查脚本是否运行whoami
- 使用
pwd
命令来验证脚本是否从正确的目录运行代码。 - 将脚本的 PATH 变量设置为与用户使用脚本中的
me
命令完全相同的路径export PATH=$PATH:/usr/local/sbin:...
- 使用 visudo 命令确保用户
me
对 Ubuntu 上的所有文件具有无限制的访问权限 - 确保用户
me
拥有该脚本并具有执行权限 - 经常对 Ubuntu 大喊大叫
还有什么问题?我没有编写 Java 代码,所以也许代码本身log4j2.xml
通过相对路径而不是绝对路径引用此文件……?但如果是这样的话,为什么手动运行时代码会起作用?
我知道这是一个开放式的问题,但是脚本和人工启动的运行此代码的版本之间还有什么不同吗?我肯定漏掉了什么...
答案1
cd
我认为脚本中您要查找的路径可能有问题。
工作时查看命令提示符mvn test
:
me@UbuntuV2:~/home/me/path/to/Java/Code$ mvn test
前导~
表示$HOME
位于显示的路径之前,这意味着完整路径实际上是。这与脚本中的/home/me/home/me/path/to/Java/Code
位置不同。/home/me/path/to/Java/Code