【Linux】shell调用Java程序main方法通过crontab定时执行

本文介绍了如何在Linux环境中通过shell脚本来调用Java程序的main方法,并使用crontab进行定时执行。创建了包含bin、libs、lock和logs目录的结构,将jar包放入相应位置,并编写shell脚本设置classpath,调用java执行main方法。通过crontab设置定时任务,利用flock防止并发执行,确保任务的有序进行。同时提供了调试shell和crontab日志的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近一个项目需要写一个batch定时读取文件往数据库里插入记录,第一次写,遇到好多问题,记录一下。


先从shell如何调用java说起

建立如下目录结构

batch                          根目录
├── bin                    shell放置目录(如果直接放java class也放这里)
│   ├── 1.sh
│   ├── test.sh
│   └── startup.sh
├── libs                   引用jar包放置目录
│   ├── commons-io-2.4.jar
│   ├── commons-lang3-3.3.2.jar
│   ├── ini4j-0.5.4.jar
│   ├── junit-3.8.1.jar
│   ├── log4j-1.2.17.jar
│   ├── postgresql-9.3-1102-jdbc41.jar
│   └── myjar.jar   自己的jar
├── lock                 锁文件(空文件)
└── logs                 程序log目录
    ├── cron.log
    └── myjar.log


然后是shell脚本

startup.sh

#!/bin/sh
echo ""
echo "----------------------------------"
echo "start at `date '+%Y-%m-%d %H:%M:%S'` ..."

JAVA_HOME=/usr/java/jdk1.8.0_45
MAIN_CLASS=com.superbatch.batch.DetectLogBatch
SH_DIR=/usr/local/ee4one_batch/bin

cd $SH_DIR
dir="."
temp=""
libs="../libs/*"

append(){
  temp=$temp":"$1
}

for file in $libs
do
  append $file
done

export CLASSPATH=$dir:../$temp

echo $CLASSPATH

#nohup
${JAVA_HOME}/bin/java -classpath ${CLASSPATH} ${MAIN_CLASS}


echo "finished at `date '+%Y-%m-%d %H:%M:%S'` ..."
exit 0

第1行声明shell类型

2-4行输出一些时间信息

 

6-8行分别定义了一些变量后面会用到

10行让程序进入到自己shell脚本的bin目录,如果使用cron执行这很重要,因为libs文件夹定义的是相对路径,而cron的默认执行路径则找不到,如果手工进入到bin目录下执行则无所谓

11-24行只做了一件事情,就是将bin目录,batch目录,libs目录下的所有jar包,全部加入到classpath中,生成一长串字符串如下:

.:../:../libs/commons-io-2.4.jar:../libs/commons-lang3-3.3.2.jar:../libs/ini4j-0.5.4.jar:../libs/junit-3.8.1.jar:../libs/log4j-1.2.17.jar:../libs/postgresql-9.3-1102-jdbc41.jar:../libs/myjar.jar

只不过是用了一个append()方法和一个for循环实现了字符串的拼接,如果jar包不多的话手工写上去也是完全可以的。

26行打印了一下生成的$CLASSPATH变量的值

29行是真正的调用java执行main()方法,要说的是 在前面如果加上“nohup ”的话,java的执行log就会直接输出到当前目录下的nohup.log文件里。如果是手工执行在最后加上“ $”的话程序将会后台执行,也就是说关闭命令行窗口并不会中断程序的执行,不过这种方法中shell的进程并不会等待java方法执行完成,而是立即完成

-classpath 后面的$CLASSPATH是告诉java去什么地方找到用到的jar包,我的程序是导出的jar包,我也同样把我的jar包放入到了这个目录就可以了,如果是编译的class文件的话放到bin目录下也可以。

32行输出log

33行程序正常退出


如果是手工通过shell调用java那以上文字就已经搞定了



下面说如何通过crontab调用shell

在命令行下输入

crontab -e

可以打开cron任务的编辑界面

注意的是cron是区分用户的,每个用户的cron是单独的

*/1 * * * * /usr/local/batch/bin/startup.sh

这样写的话就是每分钟执行一次指定的shell了

前面的几个* 分别是minute(分),hour(小时),day of month(日期),month(月份), day of week(星期),具体的可以查询一下

这个只是每分钟执行一次,下面的命令可以将执行的log输入到指定文件也就是shell中的echo

*/1 * * * * /usr/local/batch/bin/startup.sh >>/usr/local/batch/logs/cron.log

但是有好多时候,比如我的需求,如果数据量过大,上一个batch还没执行完则不希望下一个batch也执行,本次不执行就可以了这个需求可以通过flock来实现

*/1 * * * *  flock -xw 10 /usr/local/ee4one_batch/lock -c "sh /usr/local/ee4one_batch/bin/test.sh >> /usr/local/ee4one_batch/logs/cron.l


上面的命令前面就是用flock命令去给一个文件上锁,这个锁是一个全局锁如果其它命令也来获取这个文件的锁的而获取不到的话则不会被执行,这个锁文件是什么文件无所谓。

后面的参数是获取一个独占锁,如果获取不到,则等待10秒钟

-
### 设置 Cron 来定时执行 Java 和 Python 脚本 #### 配置环境变量 为了确保 cron 可以找到所需的解释器(如 `java` 或 `python3`),建议在脚本顶部显式指定路径。可以使用 `which java` 和 `which python3` 命令查找这些命令的实际位置。 对于 Python 脚本,在文件开头添加如下 shebang 行: ```bash #!/usr/bin/env python3 ``` 对于 Java 程序,则不需要类似的 shebang 行,因为通常会通过命令调用编译后的 `.class` 文件或 JAR 包。 #### 创建可执行脚本 创建两个独立的 shell 脚本来分别运行 Java 和 Python 应用程序,并赋予它们可执行权限: ##### test_java.sh ```bash #!/bin/bash # 执行已编译好的 Java 类 cd /path/to/java/project && \ javac Main.java && \ java Main ``` ##### test_python.sh ```bash #!/bin/bash # 运行 Python 脚本 /path/to/python/venv/bin/python3 /path/to/script/test.py ``` 使这两个 Shell 脚本具有可执行权能: ```bash chmod +x test_java.sh test_python.sh ``` #### 添加 Crontab 作业 编辑当前用户的 crontab 文件: ```bash crontab -e ``` 向其中加入新的调度任务条目。例如,每分钟执行一次上述脚本: ``` * * * * * /full/path/to/test_java.sh >> ~/cron.log 2>&1 */5 * * * * /full/path/to/test_python.sh >> ~/cron.python.log 2>&1 ``` 这里假设希望 Java 程序每隔一分钟被执行一次,而 Python 脚本则是在每个整点时刻被触发。日志重定向有助于诊断潜在的问题[^1]。 #### 启动并验证 Cron 服务状态 确认 cron 服务正在运行;如果不是,请启动它: ```bash sudo service cron start ``` 检查 cron 的工作状况以及最近的日志记录: ```bash systemctl status cron.service tail -f ~/cron.log tail -f ~/cron.python.log ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值