当前位置:首页>开发>正文

java中如何执行linux命令 如何在java程序中调用linux命令或者shell脚本

2023-07-18 12:39:40 互联网 未知 开发

 java中如何执行linux命令 如何在java程序中调用linux命令或者shell脚本

java中如何执行linux命令

执行linux命令基,基本思路是从控制台获得输入的指令,启动命令行执行命令,捕捉异常,示例如下:
public class TestRunTime {

    public static void main(String[] args) throws IOException, InterruptedException {
        String cmd = ""

        if(args == null || args.length == 0){
            System.out.println("请输入命令行参数")
        }else{

            for(int i=0i                cmd  = args[i]   " "
            }
        }
        try {
            Process process = Runtime.getRuntime().exec(cmd)//执行命令

            InputStreamReader ir = new InputStreamReader(process.getInputStream())
            LineNumberReader input = new LineNumberReader(ir)

            String line
            while ((line = input.readLine()) != null) {//输出结果
                System.out.println(line)
            }
        } catch (java.io.IOException e) {
            System.err.println("IOException "   e.getMessage())//捕捉异常
        }
    }
}

如何在java程序中调用linux命令或者shell脚本

在java程序中如何调用linux的命令?如何调用shell脚本呢?

这里不得不提到java的process类了。

process这个类是一个抽象类,封装了一个进程(你在调用linux的命令或者shell脚本就是为了执行一个在linux下执行的程序,所以应该使用process类)。

process类提供了执行从进程输入,执行输出到进程,等待进程完成,检查进程的推出状态,以及shut down掉进程。

至于详细的process类的介绍放在以后介绍。

另外还要注意一个类:Runtime类,Runtime类是一个与JVM运行时环境有关的类,这个类是Singleton的。

这里用到的Runtime.getRuntime()方法是取得当前JVM的运行环境,也是java中唯一可以得到运行环境的方法。(另外,Runtime的大部分方法都是实例方法,也就是说每次运行调用的时候都需要调用到getRuntime方法)

下面说说Runtime的exec()方法,这里要注意的有一点,就是public Process exec(String [] cmdArray, String [] envp)这个方法中cmdArray是一个执行的命令和参数的字符串数组,数组的第一个元素是要执行的命令往后依次都是命令的参数,envp感觉应该和C中的execve中的环境变量是一样的,envp中使用的是name=value的方式。

下面说一下,如何使用process来调用shell脚本

例如,我需要在linux下实行linux命令:sh test.sh,下面就是执行test.sh命令的方法:

这个var参数就是日期这个201102包的名字。

String shpath="/test/test.sh" //程序路径

Process process =null

String command1 = “chmod 777 ” shpath
process = Runtime.getRuntime().exec(command1)
process.waitFor()

String var="201102" //参数

String command2 = “/bin/sh ” shpath ” ” var
Runtime.getRuntime().exec(command2).waitFor()

java调用linux终端命令,如何使终端不直接退出

使用Java调用Linux的命令的都是使用这个语句RunTime.getRunTime().exec("ls -al")
import java.io.*
public class Test{

public static void main(String[] args) throws Exception{
try{
Process process=Runtime.getRuntime().exec("ls ./")
InputStreamReader reader = new InputStreamReader(process.getInputStream())
LineNumberReader line = new LineNumberReader(reader)
String str
while((str=line.readLine())!=null){
System.out.println(str)
}

}catch (Exception e){
e.printStackTrace()
}
System.out.println("done !!!")
}
}

如何调用Linux内核函数

注意看这个文件
sysdeps/unix/sysv/linux/syscalls.list
里面记录着系统调用的名字和一些属性,具体我也没有研究过,不懂。
再看select的实现,很让人惊讶,一旦使用,结果就是“报错“。
int
__select (nfds, readfds, writefds, exceptfds, timeout)
int nfds
fd_set *readfds
fd_set *writefds
fd_set *exceptfds
struct timeval *timeout
{
__set_errno (ENOSYS)
return -1
}
libc_hidden_def (__select)
stub_warning (select)
weak_alias (__select, select)
这是因为glibc并没有实现系统调用,而是调用系统调用,
更进一步,连调用系统调用都没有一个个实现,而是使用了通用的办法,
理由很简单,所有的系统调用在linux内核头文件里都能找到,
所有的系统调用参数类型就那么几种,参数个数也是有限的,
因此没有必要针对所有的系统调用一一封装,
于是就有了这个list文件,自动生成调用系统调用的函数,
如果生成失败,也就是你看到的“报错”。
符号是有强弱的,当自动生成成功的时候,“报错”的弱符号就被忽略了。
当你在glibc中找到一个系统调用的封装源码,是以下原因,
1. 编译的目标系统不支持这个系统调用,所以自己用另一种方式实现了。
2. 这个系统调用无法使用通用的自动生成方式生成,用特化的方式覆盖。
3. 针对这个系统调用做了特别的优化。
4. 其它可能的原因。
具体可以留意
SYSCALL, PSEUDO, DO_CALL, INLINE_CALL 等名字
这两个文件是重点所在
sysdeps/unix/i386/sysdep.h
sysdeps/unix/i386/sysdep.S
要搞清楚具体的自动生成过程,恐怕得研究glibc自身的编译过程了