【问题标题】:Run a shell file in java在java中运行一个shell文件
【发布时间】:2017-12-04 15:24:19
【问题描述】:

Java 你可以这样调用一个shell文件:

public class Shell {
    private static Shell rootShell = null;
    private final Process proc;
    private final OutputStreamWriter writer;

    private Shell(String cmd) throws IOException {
        this.proc = new ProcessBuilder(cmd).redirectErrorStream(true).start();
        this.writer = new OutputStreamWriter(this.proc.getOutputStream(), "UTF-8");
    }

    public void cmd(String command)  {
        try {
            writer.write(command+'\n');
            writer.flush();
        } catch (IOException e) {   }
    }

    public void close() {
        try {
            if (writer != null) {  
                writer.close();
                if(proc != null) {  
                    proc.destroy();
                }
            }
        } catch (IOException ignore) {}
    }

    public static void exec(String command) {
        Shell.get().cmd(command);   
    }

    public static Shell get() {
        if (Shell.rootShell == null) {
            while (Shell.rootShell == null) {
                try {   
                    Shell.rootShell = new Shell("su"); //Open with Root Privileges 
                } catch (IOException e) {   }
            }
        } 
        return Shell.rootShell;
    }
}

Shell.exec("echo " + bt.getLevel() + " > "+ flashfile);     

对。
但我有一个 shell,它在执行后给出一个参数。
我怎样才能通过那个论点?我不希望用户键入任何内容来运行此 shell 文件。换句话说,我想完全自动化一个 shell 文件。

【问题讨论】:

  • 您的意思是 shell 脚本需要在 STDIN 上输入?顺便说一句,如果“su”像这样工作,我会感到惊讶。它实际上只从实际终端(或命令行)获取密码。如果这是你想要的,我找到了一个解决方案(让 Java “su”成为它自己的副本)。
  • 你看到公众免费的在线文档了吗? docs.oracle.com/javase/7/docs/api/index.html?java/util/…
  • 我认为链接错误,它将我引导至 Locale.class
  • 您能否使用sudo 而不是su 来运行您的任务?

标签: java linux shell


【解决方案1】:

如果你想用 Java 程序自动化一个 shell 文件,这是可以做到的。您甚至可以通过管道将一系列命令保存在文件中并作为批处理执行。

您可以像这样执行命令批量命令:

java -cp experiments-1.0-SNAPSHOT.jar ConsoleReader < commands.txt

commands.txt 是一个包含一系列命令的文件:

cmd /k date
cmd /k dir
netstat
ipconfig

或者你可以用同一个程序让用户在命令行上执行命令。

您可以在下面找到一个示例程序,您可以按照上述方式编译和运行它。

它有什么作用?

  1. 它将java.util.Scanner 连接到控制台输入并使用每一行。
  2. 然后它生成两个线程,它们侦听错误和输入流并写出到stderrstdin
  3. 控制台上的空行被忽略
  4. 如果您键入“read”,它将执行该文件上的命令。

来源:

public class ConsoleReader {

    public static void main(String[] args) throws IOException, DatatypeConfigurationException {
        try(Scanner scanner = new Scanner(new BufferedInputStream(System.in), "UTF-8")) {
            readFromScanner(scanner);
        }
    }

    private static final Pattern FILE_INPUT_PAT = Pattern.compile("read\\s*([^\\s]+)");

    private static void readFromScanner(Scanner scanner) {
        while (scanner.hasNextLine()) {
            try {
                String command = scanner.nextLine();
                if(command != null && !command.trim().isEmpty()) {
                    command = command.trim();
                    if("exit".equals(command)) {
                        break; // exit shell
                    }
                    else if(command.startsWith("read")) { // read from file whilst in the shell.
                        readFile(command);
                    }
                    else {
                        Process p = Runtime.getRuntime().exec(command);
                        Thread stdout = readFromStream(p.getInputStream(), System.out, "in");
                        Thread stderr = readFromStream(p.getErrorStream(), System.err, "err");
                        stdout.join(200);
                        stderr.join(200);
                    }
                }
            }
            catch(Exception e) {
                Logger.getLogger("ConsoleReader").log(Level.SEVERE, String.format("Failed to execute command %s", e));
            }
        }
    }

    private static void readFile(String command) throws FileNotFoundException {
        Matcher m = FILE_INPUT_PAT.matcher(command);
        if(m.matches()) {
            String file = m.group(1);
            File f = new File(file);
            if (f.exists()) {
                try (Scanner subScanner = new Scanner(f)) {
                    readFromScanner(subScanner);
                }
            }
        }
        else {
            System.err.printf("Oops, could not find '%s'%n", command);
        }
    }

    private static Thread readFromStream(InputStream stdin, PrintStream out, String name) throws IOException {
        Thread thread = new Thread(() -> {
            try (BufferedReader in = new BufferedReader(new InputStreamReader(stdin))) {
                String line;
                while ((line = in.readLine()) != null) {
                    out.println(line);
                }
            } catch (IOException e) {
                Logger.getLogger("ConsoleReader").log(Level.SEVERE, "Failed to read from stream.", e);
            }
        }, name);
        thread.setDaemon(true);
        thread.start();
        return thread;
    }
}

【讨论】:

    【解决方案2】:

    Runtime.getRuntime().exec("src/[FILE LOCATION]");

    我认为这是您正在寻找的命令。让我知道它是否有效!

    【讨论】:

    • 不,我不想只运行一个 shell 文件,因为我说过我的 shell 在执行之前和执行 shell 文件之后有两种参数,我的问题是第二种类型。运行shell后如何输入参数
    • argument after running shell 是什么意思?
    猜你喜欢
    • 2021-04-04
    • 2021-08-08
    • 2015-07-02
    • 2018-08-10
    • 2018-05-01
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多