【问题标题】:Synology Scheduler .sh java command not found未找到 Synology Scheduler .sh java 命令
【发布时间】:2020-02-12 09:20:03
【问题描述】:

我有一个 bash 脚本,唯一的任务就是执行一个 jar 文件。

sms.sh

java -jar /volume1/homes/jar/smssender.jar

使用我的 Synology NAS 我设置了一项任务。

添加执行 bash 脚本的命令。添加日志输出。

执行我的新任务。

查看日志发现如下错误:

/volume1/homes/jar/sms.sh:第 1 行:java:找不到命令

检查 Java 版本/安装:

手动检查 sh 脚本的执行(工作):

有人遇到过同样奇怪的情况吗?任何解决方法/想法?

我试过了

  • 重新启动我的 NAS
  • 卸载/安装 Java8 包

但没有任何效果。

【问题讨论】:

  • 鉴于您的问题,可能是在执行作业时未正确设置 env (JAVA_HOME, PATH) 的问题。您应该使用 java 可执行文件的绝对路径,或者为您提供一个文件。
  • @NoDataFound 绝对路径是什么意思? /volume1/(...)/file.jar 不是路径吗?感谢您的帮助和时间
  • 首先,找到 java 可执行文件。然后,使用/whatever/path/to/java/is/java /volume1/homes/jar 调用它(这不是特定于 Synology)
  • 我们可能应该在这里补充一点,最终运行命令的用户可能不是 OP 正在登录的用户(除非他确定是),因此具有不同的 PATH。
  • (另外:这真的是话题吗?)

标签: java bash synology


【解决方案1】:

当 Synology 任务计划程序执行脚本 sms.sh 时,PATH 设置取自脚本 /etc/crontab。其中不包含 Java 路径。

默认登录 shell 环境定义为 int /etc/profile。最后有一段添加Java路径。

PATH=$PATH:/var/packages/Java8/target/j2sdk-image/bin # Synology Java runtime enviroment
PATH=$PATH:/var/packages/Java8/target/j2sdk-image/jre/bin # Synology Java runtime enviroment
JAVA_HOME=/var/packages/Java8/target/j2sdk-image/jre # Synology Java runtime enviroment
CLASSPATH=.:/var/packages/Java8/target/j2sdk-image/jre/lib # Synology Java runtime enviroment
LANG=en_US.utf8 # Synology Java runtime enviroment
export CLASSPATH PATH JAVA_HOME LANG # Synology Java runtime enviroment

正如已经给定的 cmets 中所述,不建议使用用于交互式 shell 的配置文件脚本。您可以在 sms.sh 脚本中模仿 /etc/profile 脚本的行为来设置 CLASSPATH PATH JAVA_HOME LANG。

关于在脚本中硬编码路径以及由此导致的可移植性降低的问题在这种特定情况下可能具有爱好者优先级。

【讨论】:

  • 您的回答对我帮助很大,而且是正确的,但我在手机上点错了,把 100 分给了下面的用户。真的很抱歉
  • @piguy 那是现场直播。 ;-)
【解决方案2】:

我不熟悉Synology 所以fwiw ...

shell 脚本在命令行执行时可以工作,因为特定的登录会话已经加载了一组环境变量(例如,在登录主目录中的 .profile/.bashrc 脚本时,源目录中的各种 java - 加载特定的环境变量 - PATH, JAVA_HOME, CLASSPATH 等),允许 java 和脚本运行而不会出现问题。

失败的Synology作业错误表明尚未加载特定于java的环境变量,因此作业/脚本无法找到java

假设 Synology 没有规定预加载登录配置文件的配置设置/标志,“简单”的解决方案是编辑脚本 (sms.sh) 并让它在之前获取适当的资源文件执行任何操作(例如,调用java)。一个简单的例子:

$cat sms.sh
#!/usr/bin/bash

. ~root/.bashrc      # load the root account profile before continuing ...

java ...

注意事项

  • root 替换为运行脚本的登录名(在示例Synology 图像中,您似乎选择了root 用户,因此我的示例引用~root)李>
  • ~root/.bashrc 替换为用户配置文件的路径,以便预加载允许脚本查找java 所需的环境变量

【讨论】:

  • 请不要鼓励为交互式使用而编写的配置文件在非交互式上下文中使用——它会导致人们认为他们所做的更改是无害的(因为.bashrc 不会改变守护进程是如何运作的,对吧?)但反而会导致生产中断。
  • 更好地找到实际位置,只需在脚本本身或脚本源的专用配置文件中硬编码适当的 PATH 更新。当/etc/profile.d 而不是~/.bashrc 相关时,这也适用于不相关的情况。
  • 硬编码很难移植,尤其是在混合操作系统/版本环境中;至于使用交互式配置/资源文件与专门构建的资源/配置文件……这更多是基于开发人员编写/维护环境的个人选择问题;在过去的 20 年中,我没有/零问题......在生产环境中......在整个脚本环境中使用公共资源/配置文件,ymmv
  • 在用户的交互式文件中打点也不是可移植的(特别是考虑到发行版如何重新平衡哪些内容由哪些文件完成——一些以传统方式处理并使用.profile,一些使用@987654341 @,一些使用/etc/profile.d,一些从 PAM 设置环境变量等)。一种或另一种方式,你正在做一些不可移植的事情。至少硬编码PATH=$PATH:/whatever/specific/location修改设置,它的行为对读者来说是显而易见的(他们不需要担心它以后会不会改变)。
猜你喜欢
  • 2022-01-04
  • 2021-07-07
  • 2019-08-10
  • 1970-01-01
  • 2021-11-13
  • 2019-04-19
  • 2013-05-16
  • 2018-08-10
  • 1970-01-01
相关资源
最近更新 更多