【问题标题】:how to run a bash program from windows in unix using java如何使用java从unix中的windows运行bash程序
【发布时间】:2016-01-27 20:08:03
【问题描述】:

我正在尝试运行一个程序,该程序使用 Unix 中的 jcraft 库处理来自窗口的文件。我在建立频道后发现它总是尝试在主目录中运行程序,但我需要在单独的目录中运行。请看看我到目前为止尝试了什么,让我知道我缺少什么。

String strRemoteDir = "/home/process/input" 频道 = session.openChannel("sftp");

    channel.connect();
    System.out.println("sftp channel opened and connected.");
    channelSftp = (ChannelSftp) channel;
    // Printing Home Directory in Unix Server
    System.out.println(channelSftp.getHome());
    channelSftp.cd(strRemoteDir);
   System.out.println(channelSftp.pwd());

  // for uploading a file where i need to run the program
    File f = new File(fileName);
    channelSftp.put(new FileInputStream(f), f.getName());
    System.out.println("File transfered successfully to host.");
    fileTransfer = true;

    channel=session.openChannel("exec");
    InputStream in=channel.getInputStream();
    // it is printing the desired directory where i want to go
    System.out.println(channelSftp.pwd());
    ((ChannelExec)channel).setCommand("sh process.ksh "a.txt");
    channel.setInputStream(null);
    ((ChannelExec)channel).setErrStream(System.err);
     channel.connect();

输出:找不到 process.ksh

但是通过腻子我能够运行该程序。只是为了让您知道 process.ksh 不在输入目录中,但可以在任何地方使用参数运行。 ((ChannelExec)channel).setcommand("ls") 打印出主目录中的所有文件。我相信我正在建立一个到主目录的通道,我只是不知道如何在所需位置使用 jcraft 运行 bash 程序。请让我知道我缺少什么或者是否有可能实现它。

提前致谢。 努尔

【问题讨论】:

  • 似乎 execChannel 没有“当前目录”的概念,因此您可能需要指定 process.ksh 的完整绝对路径。如果这对当前目录有特定要求,它应该设置目录本身。 epaul.github.io/jsch-documentation/javadoc/com/jcraft/jsch/…
  • 如果我使用 ksh 文件的绝对路径并尝试执行,它会返回另一个错误,因为参数文件不存在。为了简单起见,我在脚本目录中有脚本,在数据目录中有数据。我想使用未发生的参数在数据目录中运行 ksh 程序。我能够使用附加命令更改目录仍然没有运气。有什么特殊的命令可以运行 ksh 程序吗?

标签: java linux windows


【解决方案1】:

“sftp”通道不用于执行shell命令,仅用于执行sftp命令。

    Channel channel = session.openChannel("shell");
    cmdSend = channel.getOutputStream();
    InputStream cmdRcv = channel.getInputStream();
    // Start a Thread reading and displaying cmdRcv

    channel.connect(3000);
    Thread.sleep(1000);

    cmdSend.write("cd /to/the/right/dir\n".getBytes());
    cmdSend.flush();
    cmdSend.write("sh process.ksh \"a.txt\"\n".getBytes());
    cmdSend.flush();

【讨论】:

  • 看起来它什么也没做,我如何打印错误/成功消息。任何建议请。
  • 我可以打印出来。输出是这样的:禁止使用 GenericID 进行交互式登录。在继续之前,您需要使用您的 ID 重新进行身份验证。输入您的 ID:但我已成功连接到该服务器。如果我需要再次输入凭据,我该如何输入。感谢您的回复。努尔
  • 我猜这意味着:您尝试在管理员阻止您执行命令的服务器上执行命令。
【解决方案2】:

其他人提供了如何设置工作目录的示例。然而,一种更具防御性的编程风格是不假设任何内容并明确指定所有内容。因此,对于指定要执行的命令,类似于:

/bin/sh /path/to/bin/process.ksh /path/to/data/ "a.txt"

请注意,我已为您的命令添加了一个新的第一个参数,即您要从中运行它的目录。

现在,更改您的脚本,使其更改为该目录(作为参数 $1 给出),然后再继续。

这可以通过在开头添加cd 来完成,例如:

cd $1
shift

shift 命令移动所有其他参数,使 $2 变为 $1,依此类推,这样脚本的其余部分将找到它期望的参数。

【讨论】:

  • 没有得到最后一部分。你能分享完整的例子吗
  • @nur,没有太多要添加到示例中的内容,但我已经添加了更多解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-14
相关资源
最近更新 更多