通过JSch关于java运行Linux命令(Running linux commands on ja

2019-06-26 08:29发布

我建立经过JSch在Java中的SSH连接,一切似乎做工精细,直到我试图运行这个sh文件。 shell脚本的名字是repoUpdate.sh,这是非常简单的:

echo  ' ****Repository update****'
echo  ' Location: /home/cissys/repo/'
echo -e ' Command: svn update /home/cissys/repo/2.3.0'

svn update /home/cissys/repo/2.3.0

这是输出我直接获得与命令的正确响应Linux控制台上:

[cissys@dsatelnx5 ~]$ repoUpdate.sh
 ****Repository update****
 Location: /home/cissys/repo/
 Command: svn update /home/cissys/repo/2.3.0

At revision 9432.

现在,这里是试图调用此相同的文件我的方法与SSH连接的Java代码

public void cmremove()
{
    try
    {
        JSch jsch = new JSch();
        Session session = jsch.getSession(user, host, port);
        UserInfo ui = new SUserInfo(pass, null);
        session.setUserInfo(ui);
        session.setPassword(pass);
        session.connect();

        ChannelExec channelExec = (ChannelExec)session.openChannel("exec");

        InputStream in = channelExec.getInputStream();

        channelExec.setCommand("./repoUpdate.sh");
        channelExec.connect();

        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        String line;
        int index = 0;

        while ((line = reader.readLine()) != null)
        {
            System.out.println(++index + " : " + line);
        }

        channelExec.disconnect();
        session.disconnect();

        System.out.println("Done!");
    }
    catch(Exception e)
    {
        System.err.println("Error: " + e);
    }
}

而我得到的回应是:

run:
1 :  ****Repository update****
2 :  Location: /home/cissys/repo/
3 :  Command: svn update /home/cissys/repo/2.3.0
Done!
BUILD SUCCESSFUL (total time: 2 seconds)

与svn命令(在修订9432)没有任何输出或执行的迹象。

我想它可能会在某个时候在会议闭幕,不让命令正确执行。 如果updateRepo.sh文件会一直有这样的事情“CP的test.txt test_2.txt”,那就没有问题做。 但我只有这个问题,这和其他一些特定.SH文件。

任何帮助,将不胜感激。

Answer 1:

我怀疑你的shell命令示数因故-也许svn是不是你的道路上,或许还有其他奇怪的环境影响-但你没有得到错误输出,因为你是不是在找它。 通常情况下,错误在你获得流发送channelExec.getErrStream但在你的代码,你只能从阅读getOutputStream流。

要诊断此,你将需要得到这些错误消息。 它可能更容易让Linux使用一个流为经常输出和错误消息,而不是有你的java程序同时从两个流拉动,所以我要补充这条线的顶线repoUpdate.sh

exec 2>&1

那么这会导致脚本的其余部分使用你从既输出和错误读取一个数据流。

此外,您拨打的权利之前chanelExec.disconnect ,在Java程序中你必须记录退出状态,然后改变你的“成交!” 消息基于它是什么:

    int exitStatus = channelExec.getExitStatus();
    channelExec.disconnect();
    session.disconnect();

    if (exitStatus < 0) {
        System.out.println("Done, but exit status not set!");
    } else if (exitStatus > 0) {
        System.out.println("Done, but with error!");
    } else {
        System.out.println("Done!");
    }

如果你这样做,你应该再拿到告诉你为什么,你期望它应该你的命令是行不通的错误消息。



Answer 2:

因此,这里就是我所做的。
我添加了exec 2>&1repoUpdate.sh文件的顶部,并补充说一段代码读取输出误差作为@DanielMartin建议,致使在此:

public void cmremove()
{
    try
    {
        JSch jsch = new JSch();
        Session session = jsch.getSession(user, host, port);
        UserInfo ui = new SUserInfo(pass, null);
        session.setUserInfo(ui);
        session.setPassword(pass);
        session.connect();

        ChannelExec channelExec = (ChannelExec)session.openChannel("exec");

        InputStream in = channelExec.getInputStream();

        channelExec.setCommand("./repoUpdate.sh");
        channelExec.connect();

        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        String line;
        int index = 0;

        while ((line = reader.readLine()) != null)
        {
            System.out.println(++index + " : " + line);
        }

        int exitStatus = channelExec.getExitStatus();
        channelExec.disconnect();
        session.disconnect();
        if(exitStatus < 0){
            System.out.println("Done, but exit status not set!");
        }
        else if(exitStatus > 0){
            System.out.println("Done, but with error!");
        }
        else{
            System.out.println("Done!");
        }
    }
    catch(Exception e)
    {
        System.err.println("Error: " + e);
    }
}

因此,实际上帮助了很多。 这证实了此命令,其实,不执行正确,因为我以为。 我在我的Java输出得到这个:

run:
1 :  ****Repository update****
2 :  Location: /home/cissys/repo/
3 :  Command: svn update /home/cissys/repo/2.3.0
4 : ./repoUpdate.sh[6]: svn: not found [No such file or directory]
Done!
BUILD SUCCESSFUL (total time: 2 seconds)

然后我试图修改repoUpdate.sh文件,增加的绝对路径svn命令(谢谢你,@ymnk)

exec 2>&1
echo  ' ****Repository update****'
echo  ' Location: /home/cissys/repo/'
echo -e ' Command: svn update /home/cissys/repo/2.3.0'

/opt/subversion/bin/svn update /home/cissys/repo/2.3.0

对于我的Java,我正是我一直在寻找:

run:
1 :  ****Repository update****
2 :  Location: /home/cissys/repo/
3 :  Command: svn update /home/cissys/repo/2.3.0
4 : At revision 9443.
Done!
BUILD SUCCESSFUL (total time: 3 seconds)

我发现在$PATH我从会议上获得通过Java是不一样的,我直接拿到Linux控制台上。 所以加入SVN路径实际上做的伎俩。 非常感谢您的帮助!



Answer 3:

如何使用“的svn”命令的绝对路径?



文章来源: Running linux commands on java through JSch