我用Java编写代码,使用Runtime,执行Linux命令。
比如执行:“hive -f 'hivetest.sh'”,hivetest.sh是Linux上面的一个脚本(关于hive的建表、load数据等等。)
我的问题是:怎么获取这个脚本的执行状态(脚本中的命令是成功了还是失败了)。
脚本执行过程中根据状态用“echo”输出日志信息。如下:
echo "stop goods"
for((i=1;i<=5;i++));
do
pid=ps -ef | grep dmw-goods.jar | grep java | grep -v grep | awk '{print $2}'
if [ -n "$pid" ]
then
echo “旧应用进程id:$pid”
kill -15 $pid
sleep 3
else
echo "安全退出"
break
fi
done
pid=ps -ef | grep dmw-goods.jar | grep java | grep -v grep | awk '{print $2}'
if [ -n "$pid" ]
then
echo "安全退出失败强制退出kill-9"
kill -9 $pid
fi
echo "执行...."
cd /data/work/soft/
chmod 777 dmw-goods.jar
nohup java -jar -Dspring.profiles.active=demo dmw-goods.jar > /dev/null &
echo "启动成功"
上面脚本尝试安全退出目标进程,退出成功重启,打印日志。
在执行这个脚本时指定日志输出文件路径“/data/work/soft/goods-start.sh >> /tmp/log.txt”
然后就可以在日志文件中查看脚本执行情况。
具体在你的问题中,你可以在脚本正常执行完时输出特定的成功标识。实际在具体业务中,应该去判断对应的表是否存在,数据是否load
这是搜到的一个大神写的.
我之前也是在这样写的,但是没想到process.waitFor()还有返回值,并且返回值就是执行状态,要多难受就多难受。
public static void execute(String shellString) {
try {
Process process = Runtime.getRuntime().exec(shellString);
int exitValue = process.waitFor();
if (0 != exitValue) {
log.error("call shell failed. error code is :" + exitValue);
}
} catch (Throwable e) {
log.error("call shell failed. " + e);
}
}
Java 执行 Linux 脚本,是可以用线程读取返回值信息的,返回值在响应流中:
Process process1 = null;
Process process2 = null;
try {
process1 = Runtime.getRuntime().exec(command1); // 执行添加权限的命令
process1.waitFor(); // 如果执行多个命令,必须加上
ProcessBuilder processBuilder = new ProcessBuilder(commandList);
processBuilder.redirectErrorStream(true);
process2 = processBuilder.start();
//处理InputStream的线程
final BufferedReader in = new BufferedReader(new InputStreamReader(process2.getInputStream()));
new Thread() {
@Override
public void run() {
String line = null;
try{
while((line = in.readLine()) != null) {
strList.add(line);
}
}catch(IOException e) {
e.printStackTrace();
}finally {
if(in != null){
try {
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
}.start();
process2.waitFor();
log.debug("执行 Shell 脚本完成");
} catch (IOException e) {
log.error("执行 Shell 时,出现IO异常,设置失败",e);
} catch (InterruptedException e) {
log.error("出现InterruptedException异常",e);
}finally {
if(process1 != null){
process1.destroy();
}
if(process2 != null){
process2.destroy();
}
}
而且,如果脚本执行输出信息太多,而 Java 程序端又没有读取缓冲区的数据的话,会出现缓冲区满、程序死锁的问题的。真实踩过的坑:
https://blog.csdn.net/wojiushiwo945you/article/details/80073227